# HG changeset patch # User bugtracker-ml@nttdocomo.com # Date 1270569622 -3600 # Node ID f24810eebc6bbc306804582f396237eb5e7345b9 # Parent fc9fa34e0c9efb8eb069f9bb86e85b265f27ee3e# Parent 2c1e559d48bf3bf196542eceb497e95f1047ff11 Merge BUG 1296 diff -r 2c1e559d48bf -r f24810eebc6b .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,3 @@ +syntax: glob + +*~ diff -r 2c1e559d48bf -r f24810eebc6b .hgtags --- a/.hgtags Tue Apr 06 16:31:41 2010 +0100 +++ b/.hgtags Tue Apr 06 17:00:22 2010 +0100 @@ -1,3 +1,6 @@ 5c4b0c1fa5f84f299d50ad82f561454aa109a2a4 PDK_3.0.b c506b18dc03fca6edca100e3b2cd2ae4c175215c PDK_3.0.c c506b18dc03fca6edca100e3b2cd2ae4c175215c PDK_2.0.1 +1a93ed2e38bd484d72fdaa19792e0f9568455b8a PDK_3.0.d +1a93ed2e38bd484d72fdaa19792e0f9568455b8a PDK_2.0.2 +7048876724acc5d17377ab5ff1747863859d4efc PDK_3.0.e diff -r 2c1e559d48bf -r f24810eebc6b README.txt --- a/README.txt Tue Apr 06 16:31:41 2010 +0100 +++ b/README.txt Tue Apr 06 17:00:22 2010 +0100 @@ -1,5 +1,8 @@ This is repo contains the following; +applications/ + Sample application + baseport/ The baseport (BSP) needed to run Symbian OS in QEMU @@ -12,6 +15,13 @@ A corresponding set of Windows/Linux binaries is available from the Symbian Foundation wiki http://developer.symbian.org/wiki/index.php/SYBORG/QEMU +tools/e32test-driver/ + A simple python script to run the E32test-suite and collect/summarize the results. + +tools/elf4rom/ + The ELF4ROM command line tool and libraries. This tool is used to convert Symbian ROM images + into debuggable elf files. See docs/wiki/ELF4ROM.doc for more information. + Some notes; * The source layout for baseport now matches the Symbian Foundation layout, and diff -r 2c1e559d48bf -r f24810eebc6b applications/SymbianLogo_TextShell/BLD.INF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/applications/SymbianLogo_TextShell/BLD.INF Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,22 @@ +/******************************************************************************* +* Copyright (c) 2009 Accenture +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Accenture - Johnathan White + +*******************************************************************************/ + +PRJ_PLATFORMS +ARMV5 + +PRJ_EXPORTS +symbian_logo.bmp \svphostfs\symbian_logo.bmp +symbianlogo.iby \epoc32\rom\include\symbianlogo.iby + +PRJ_MMPFILES +SymbianLogo + diff -r 2c1e559d48bf -r f24810eebc6b applications/SymbianLogo_TextShell/README.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/applications/SymbianLogo_TextShell/README.txt Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,30 @@ +/******************************************************************************* +* Copyright (c) 2009 Accenture +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Accenture - Johnathan White + +*******************************************************************************/ + +Submitter - Johnathan.White@accenture.com + +Purpose - Simple TextShell console application which reads image file from filesystem and outputs to display + +Build from - \sf\adaptation\qemu\applications\SymbianLogo_TextShell + +Using command - sbs -b bld.inf -c armv5 -j 1 + +To include in textshell build modify \sf\os\kernelhwsrv\kernel\eka\rombuild\tshell.oby and add the line - + +#include + +Then Build textshell rom from \sf\os\kernelhwsrv\kernel\eka\rombuild\ using command - rom -v syborg -i armv5 -b udeb -noheader + +Then run QEMU from \symbian-qemu-0.9.1\bin using command - + +arm-none-symbianelf-qemu-system.exe -kernel \sf\os\kernelhwsrv\kernel\eka\rombuild\syborgarmv5d.img -M \sf\adaptation\qemu\baseport\syborg\syborg.dtb + diff -r 2c1e559d48bf -r f24810eebc6b applications/SymbianLogo_TextShell/SymbianLogo.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/applications/SymbianLogo_TextShell/SymbianLogo.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,101 @@ +/******************************************************************************* +* Copyright (c) 2009 Accenture +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Accenture - Johnathan White + +*******************************************************************************/ +// SymbianLogo.cpp + +#include +#include +#include +#include +#include + +void SetupConsoleL(); +void DisplayLogoL(CConsoleBase* aConsole); + +CConsoleBase* console; + +GLDEF_C TInt E32Main() + { + CTrapCleanup* cleanup=CTrapCleanup::New(); + TRAPD(error,SetupConsoleL()); + if(error) + RDebug::Printf("SymbianLogo SetupError %d", error); + delete cleanup; + return 0; + } + +void SetupConsoleL() + { + console=Console::NewL(_L("SymbianLogo"), + TSize(KConsFullScreen,KConsFullScreen)); + + CleanupStack::PushL(console); + TRAPD(error,DisplayLogoL(console)); + if(error) + RDebug::Printf("SymbianLogo DisplayLogo Error %d", error); + CleanupStack::PopAndDestroy(); + } + + +GLDEF_C void DisplayLogoL(CConsoleBase* aConsole) + { + TInt err =KErrNone; + + //Connect to FileServer + RFs fs; + err = fs.Connect(); + + User::LeaveIfError(err); + + //Open file + + /* + File \sf\adaptation\qemu\baseport\syborg\syborg.dts contains board model description, the hostfs@0 block defines both the host path + and target drive. The hostpath is by default set to \svphostfs\ and default drive number is 19 (S:\). If you would like to change this + edit the dts file and use arm-none-symbianelf-dtc.exe to create updated dtb file + */ + RFile file; + err = file.Open(fs, _L("S:\\symbian_logo.bmp"), EFileRead); + + User::LeaveIfError(err); + + //Use to read stream from file on HostFs, first 54 bytes are header so skip + /* + symbian_logo.bmp is a 480*480 bmp file + */ + RFileReadStream filestream(file, 54); + + + //Obtain base address of framebuffer which will copy bitmap data into to display + TInt iScreenAddress; + HAL::Get(HAL::EDisplayMemoryAddress, iScreenAddress); + TUint8* pointer = (TUint8*)iScreenAddress; + + + + + pointer+=640*479*4; //bitmap is 480*480 where as display is 640 *640, start by incrementing display pointer to last line required + for(TInt i=0;i<480;i++) + { + for(TInt j=0;j<1920;j++) + { + *pointer = filestream.ReadUint8L(); //reads byte from file into correct offset in framebuffer + pointer++; + } + + pointer-=1920; //decrement over offset between each line + pointer-=640*4; //decrement to start of next line + } + + //Wait for User to press key then return + aConsole->Getch(); + return; + } diff -r 2c1e559d48bf -r f24810eebc6b applications/SymbianLogo_TextShell/SymbianLogo.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/applications/SymbianLogo_TextShell/SymbianLogo.iby Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,23 @@ +/******************************************************************************* +* Copyright (c) 2009 Accenture +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Accenture - Johnathan White + +*******************************************************************************/ + +#ifndef __SYMBIANLOGO_IBY__ +#define __SYMBIANLOGO_IBY__ + + +//actual logo console app +file=\epoc32\release\armv5\urel\symbianlogo.exe sys\bin\symbianlogo.exe + +//library containing RFileReadStream +file=\epoc32\release\armv5\urel\estor.dll sys\bin\estor.dll + +#endif \ No newline at end of file diff -r 2c1e559d48bf -r f24810eebc6b applications/SymbianLogo_TextShell/SymbianLogo.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/applications/SymbianLogo_TextShell/SymbianLogo.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,18 @@ +/******************************************************************************* +* Copyright (c) 2009 Accenture +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Accenture - Johnathan White + +*******************************************************************************/ + +TARGET SYMBIANLOGO.EXE +TARGETTYPE EXE +SOURCEPATH . +SOURCE symbianlogo.cpp +OS_LAYER_SYSTEMINCLUDE +LIBRARY efsrv.lib euser.lib hal.lib estor.lib diff -r 2c1e559d48bf -r f24810eebc6b applications/Symbian_MiniGUI_TestApp/BLD.INF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/applications/Symbian_MiniGUI_TestApp/BLD.INF Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,21 @@ +/******************************************************************************* +* Copyright (c) 2009 Accenture +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Accenture - Johnathan White + +*******************************************************************************/ + +PRJ_PLATFORMS +ARMV5 + +PRJ_EXPORTS +grid.iby \epoc32\rom\include\grid.iby + +PRJ_MMPFILES +grid + diff -r 2c1e559d48bf -r f24810eebc6b applications/Symbian_MiniGUI_TestApp/Grid.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/applications/Symbian_MiniGUI_TestApp/Grid.iby Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,21 @@ +/******************************************************************************* +* Copyright (c) 2009 Accenture +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Accenture - Johnathan White + +*******************************************************************************/ + +#ifndef __SYMBIANMINIGUI_TESTAPP_IBY__ +#define __SYMBIANMINIGUI_TESTAPP_IBY__ + + +//actual logo console app +file=\epoc32\release\armv5\urel\grid.exe sys\bin\grid.exe + + +#endif \ No newline at end of file diff -r 2c1e559d48bf -r f24810eebc6b applications/Symbian_MiniGUI_TestApp/Grid.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/applications/Symbian_MiniGUI_TestApp/Grid.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,18 @@ +/******************************************************************************* +* Copyright (c) 2009 Accenture +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Accenture - Johnathan White + +*******************************************************************************/ + +TARGET grid.EXE +TARGETTYPE EXE +SOURCEPATH . +SOURCE grid.cpp +OS_LAYER_SYSTEMINCLUDE +LIBRARY efsrv.lib euser.lib hal.lib ws32.lib diff -r 2c1e559d48bf -r f24810eebc6b applications/Symbian_MiniGUI_TestApp/grid.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/applications/Symbian_MiniGUI_TestApp/grid.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,83 @@ +#include +#include "profiler.h" + +const TSize KSize(64,60); +const TInt KRow = 4; +const TInt KCol = 5; + +void MainL() + { + RWsSession ws; + ws.Connect(); + CWsScreenDevice* scr = new(ELeave) CWsScreenDevice(ws); + scr->Construct(); + CWindowGc* gc = new(ELeave) CWindowGc(scr); + gc->Construct(); + RWindowGroup grp(ws); + grp.Construct(0xc0decafe, ETrue); + RWindow win(ws); + win.Construct(grp, 0xbeefcafe); + win.SetExtent(TPoint(20,160), TSize(320,240)); + win.Activate(); + win.Invalidate(); + win.BeginRedraw(); + gc->Activate(win); + gc->SetPenStyle(CGraphicsContext::ENullPen); + gc->SetBrushStyle(CGraphicsContext::ESolidBrush); + TBool color = EFalse; + +if (Profiler::Start() == KErrNotFound) + { + _LIT(KProfiler,"profiler"); + _LIT(KStart,"start -noui -drive=S"); + RProcess p; + if (p.Create(KProfiler,KStart) == KErrNone) + { + p.Resume(); + p.Close(); + } + } + + for (TInt col=0; colSetBrushColor(color? KRgbGray : KRgbBlack); + gc->DrawRect(rect); + } + } + gc->Deactivate(); + win.EndRedraw(); + ws.Flush(); + User::After(3000000); + win.Close(); + grp.Close(); + delete gc; + delete scr; + ws.Close(); + + Profiler::Stop(); + Profiler::Close(); + Profiler::Unload(); + + } + + +GLDEF_C TInt E32Main() +{ + + CTrapCleanup* tc = CTrapCleanup::New(); + if (!tc) + { + return KErrNoMemory; + } + TRAPD(err, MainL()); + delete tc; + return err; +} \ No newline at end of file diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/bld.inf --- a/baseport/syborg/bld.inf Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/bld.inf Tue Apr 06 17:00:22 2010 +0100 @@ -20,18 +20,26 @@ PRJ_EXPORTS syborg.oby /epoc32/rom/include/ // -base.iby /epoc32/rom/include/ // +//MattD - don't export the base.iby as you end up fighting with the kernel and everyone else... +//base.iby /epoc32/rom/include/ // rom/base_syborg.iby /epoc32/rom/include/ // rom/header.iby /epoc32/rom/syborg/ // rom/kernel.iby /epoc32/rom/syborg/ // specific/syborg.cfg /epoc32/rom/syborg/ // estart.txt /epoc32/rom/syborg/ // +syborg.dtb /epoc32/rom/syborg/ // trk_l1.ini /epoc32/data/Z/trk/trk_syborg.ini - +webcamera/webcamera_driver.h /epoc32/include/syborg/ +webcamera/webcamera_driver.inl /epoc32/include/syborg/ specific/variantmediadef.h /epoc32/include/syborg/variantmediadef.h PRJ_EXTENSIONS start extension base/genexec +#ifdef SYMBIAN_OLD_EXPORT_LOCATION +option INC_PATH /epoc32/include +#else +option INC_PATH /epoc32/include/platform +#endif option EXTRA_SRC_PATH $(EXTENSION_ROOT)/../../../../os/kernelhwsrv/kernel/eka/kernel end @@ -48,12 +56,21 @@ kasyborg // Variant library serial/serial // Serial / UART ports fb/fb // Framebuffer + + keyboard/keyboard // Keyboard pointer/pointer // Pointer + +pointer/pointer_landscape.mmp +pointer/pointer_portrait.mmp + monitor/monap // Crash Debugger output keymap/keymap // Key mapping library +estart/estart // Customised estart to kick-start hostfs files system + + // platform device library - for flattened device tree (FDT) svpplatform/fdt @@ -67,6 +84,17 @@ svpsnapdriver/svpsnapdriver svpsnapdriver/snapapp +//NGA framebuffer +svpframebuffer/svpframebuffer + +//Add Sound Driver +soundsc\soundsc + +//Webcamera Device +webcamera/webcamera_pdd +webcamera/webcamera_ldd +webcamera/webcamera_app + PRJ_EXTENSIONS start extension base/config option PREFIX _syborg_ @@ -79,6 +107,11 @@ PRJ_EXTENSIONS start extension base/bootstrap +#ifdef SYMBIAN_OLD_EXPORT_LOCATION +option INC_PATH /epoc32/include +#else +option INC_PATH /epoc32/include/platform +#endif option NAME _syborg_bootloader_bootrom option MEMMODEL multiple //option MEMMODEL flexible @@ -89,3 +122,10 @@ option EXTRA_INC_PATH $(EXTENSION_ROOT)/bootstrap option EXTRA_SRC_PATH $(EXTENSION_ROOT)/bootstrap end + +// Build image armv5 for urel and udeb +PRJ_EXTENSIONS +start extension base/rom +option REE_TARGET syborg +option TYPE tshell +end diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/bootstrap/syborg.inc --- a/baseport/syborg/bootstrap/syborg.inc Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/bootstrap/syborg.inc Tue Apr 06 17:00:22 2010 +0100 @@ -20,7 +20,11 @@ ;--------------------------------------------------------------------------- KHwRamBaseAddr EQU 0x00000000 + +; More ram required to boot SF image KHwRamSizeMb EQU 128 ; 128MB +;KHwRamSizeMb EQU 256 ; 256MB + KHwNorFlashBaseAddr EQU 0x40000000 KHwNorFlashSize EQU 0x04000000 ; 64MB @@ -47,7 +51,9 @@ KHwBaseNet EQU KHwBaseRegisters + 0x0c000 KHwBaseNand EQU KHwBaseRegisters + 0x0d000 KHwBaseAudio EQU KHwBaseRegisters + 0x0e000 -KHwBasePlatform EQU KHwBaseRegisters + 0x0f000 +KHwBaseWebcamera EQU KHwBaseRegisters + 0x0f000 +KHwBasePlatform EQU KHwBaseRegisters + 0x10000 + ;----------------------------------------------------------------------------- ; Module linear bases ;----------------------------------------------------------------------------- @@ -72,6 +78,7 @@ KHwLinBaseNet EQU KHwLinBaseRegisters + 0x0c*KHwLinSeparation KHwLinBaseNand EQU KHwLinBaseRegisters + 0x0d*KHwLinSeparation KHwLinBaseAudio EQU KHwLinBaseRegisters + 0x0e*KHwLinSeparation -KHwLinBasePlatform EQU KHwLinBaseRegisters + 0x0f*KHwLinSeparation +KHwLinBaseWebcameraDevice EQU KHwLinBaseRegisters + 0x0f*KHwLinSeparation +KHwLinBasePlatform EQU KHwLinBaseRegisters + 0x10*KHwLinSeparation; END diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/bootstrap/syborg.s --- a/baseport/syborg/bootstrap/syborg.s Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/bootstrap/syborg.s Tue Apr 06 17:00:22 2010 +0100 @@ -182,6 +182,7 @@ HW_MAPPING KHwBaseNet, 1, HW_MULT_4K HW_MAPPING KHwBaseNand, 1, HW_MULT_4K HW_MAPPING KHwBaseAudio, 1, HW_MULT_4K + HW_MAPPING KHwBaseWebcamera, 1, HW_MULT_4K HW_MAPPING KHwBasePlatform, 8, HW_MULT_4K DCD 0 ; terminator diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/estart/estart.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/estart/estart.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include + +TARGET VariantTarget(e32strt,exe) +CAPABILITY TCB WriteDeviceData DiskAdmin ProtServ AllFiles PowerMgmt + +TARGETTYPE exe + + +SOURCEPATH \sf\os\kernelhwsrv\userlibandfileserver\fileserver\estart +SOURCE estart.cpp +SOURCEPATH ../estart +SOURCE estartmain.cpp + +STRICTDEPEND + +//SOURCEPATH . +//DOCUMENT ../group/release.txt + +USERINCLUDE \sf\os\kernelhwsrv\userlibandfileserver\fileserver\estart +//SYSTEMINCLUDE ../inc /epoc32/include +SYSTEMINCLUDE /epoc32/include + +LIBRARY efsrv.lib euser.lib hal.lib +LIBRARY domaincli.lib + +//#ifdef WINS +//LIBRARY emulator.lib +//#endif + +//START WINS +//BASEADDRESS 0x62000000 +//win32_library kernel32.lib +//END + + +UID 0 0x10272C04 +VENDORID 0x70000001 + +//#include "../group/f32.mmh" // Generic definitions for the whole f32 component diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/estart/estartmain.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/estart/estartmain.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +/* + * + * This file starts the HOSTFS local drive mapping + * + */ + +#include +#include "estart.h" + +#define __ENABLE_HOSTFS + +/*! + * Customised estart class + */ +class TSyborgFSStartup : public TFSStartup + { +public: +#ifdef __ENABLE_HOSTFS + virtual void InitHostFS(); +#endif + }; + + +#ifdef __ENABLE_HOSTFS + +/* + * + * Run the Host FS starter program + * + */ +void TSyborgFSStartup::InitHostFS() + { +_LIT(KHostFSMounter, "z:\\sys\\bin\\SVPHOSTFS.EXE"); + + RProcess ws; + TInt r=ws.Create(KHostFSMounter, KNullDesC); + if (r == KErrNone) + { + TRequestStatus stat; + ws.Rendezvous(stat); + ws.Resume(); + User::WaitForRequest(stat); // wait for start or death + ws.Close(); + } + } +#endif + + +/*! + * Estart entry point + */ +GLDEF_C TInt E32Main() + { + + TSyborgFSStartup fsStart; + fsStart.Init(); + + fsStart.Run(); +#ifdef __ENABLE_HOSTFS + fsStart.InitHostFS(); +#endif + fsStart.StartSystem(); + + fsStart.Close(); + return(0); + } diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/estart/readme.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/estart/readme.txt Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,21 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +See \sf\os\kernelhwsrv\userlibandfileserver\fileserver\estart + + diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/ethernet/pdd/enet.mmp --- a/baseport/syborg/ethernet/pdd/enet.mmp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/ethernet/pdd/enet.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -22,6 +22,7 @@ TARGETTYPE pdd ROMTARGET ethernet.pdd +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) SYSTEMINCLUDE /epoc32/include/drivers SYSTEMINCLUDE AsspNKernIncludePath SOURCEPATH . diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/fb/fb.mmp --- a/baseport/syborg/fb/fb.mmp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/fb/fb.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -21,6 +21,9 @@ TARGET VariantTarget(lcd,dll) TARGETTYPE kext +MACRO __PORTRAIT_DISPLAY__ + + SYSTEMINCLUDE AsspNKernIncludePath SYSTEMINCLUDE . diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/fb/fb_landscape.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/fb/fb_landscape.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* Sosco +* +* Description: +* Variant derived from fb.mmp +* +*/ + +#include +#include "kernel/kern_ext.mmh" + +TARGET VariantTarget(lcd_landscape,dll) +TARGETTYPE kext + +SYSTEMINCLUDE AsspNKernIncludePath +SYSTEMINCLUDE . + +SOURCEPATH . +SOURCE syborg_fb.cpp + +LIBRARY PlatformLib + +EPOCALLOWDLLDATA + +UID 0x1000008d 0x100039e8 +VENDORID 0x70000001 + +ROMTARGET lcd.dll + +CAPABILITY all diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/fb/fb_portrait.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/fb/fb_portrait.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* Sosco +* +* Description: +* Variant derived from fb.mmp +* +*/ + +#include +#include "kernel/kern_ext.mmh" + +MACRO __PORTRAIT_DISPLAY__ + +TARGET VariantTarget(lcd_portrait,dll) +TARGETTYPE kext + +SYSTEMINCLUDE AsspNKernIncludePath +SYSTEMINCLUDE . + +SOURCEPATH . +SOURCE syborg_fb.cpp + +LIBRARY PlatformLib + +EPOCALLOWDLLDATA + +UID 0x1000008d 0x100039e8 +VENDORID 0x70000001 + +ROMTARGET lcd.dll + +CAPABILITY all diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/fb/fb_portrait_wvga.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/fb/fb_portrait_wvga.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* Sosco +* +* Description: +* Variant derived from fb.mmp +* +*/ + +#include +#include "kernel/kern_ext.mmh" + +MACRO __PORTRAIT_DISPLAY__ +MACRO __DISPLAY_WVGA__ + +TARGET VariantTarget(lcd_portrait_wvga,dll) +TARGETTYPE kext + +SYSTEMINCLUDE AsspNKernIncludePath +SYSTEMINCLUDE . + +SOURCEPATH . +SOURCE syborg_fb.cpp + +LIBRARY PlatformLib + +EPOCALLOWDLLDATA + +UID 0x1000008d 0x100039e8 +VENDORID 0x70000001 + +ROMTARGET lcd.dll + +CAPABILITY all \ No newline at end of file diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/fb/syborg_fb.cpp --- a/baseport/syborg/fb/syborg_fb.cpp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/fb/syborg_fb.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -11,6 +11,8 @@ * * Contributors: * +* Accenture Ltd - Syborg framebuffer improvements, now auto determines frame size from board model, performance and memory improvements +* * Description: Minimalistic frame buffer driver * */ @@ -114,10 +116,10 @@ void DLcdPowerHandler::PowerUpLcd(TBool aSecure) { -#if 1 + WriteReg(iPortAddr, FB_ENABLED, 0); WriteReg(iPortAddr, FB_BASE, aSecure ? iSecurevRamPhys : ivRamPhys); - WriteReg(iPortAddr, FB_WIDTH, iVideoInfo.iSizeInPixels.iWidth); + WriteReg(iPortAddr, FB_BLANK, 0); WriteReg(iPortAddr, FB_BPP, 32); WriteReg(iPortAddr, FB_COLOR_ORDER, 0); @@ -125,8 +127,9 @@ WriteReg(iPortAddr, FB_PIXEL_ORDER, 0); WriteReg(iPortAddr, FB_INT_MASK, 0); WriteReg(iPortAddr, FB_ENABLED, 1); - WriteReg(iPortAddr, FB_HEIGHT, iVideoInfo.iSizeInPixels.iHeight); -#endif + + // We don't write the Height and Width of the framebuffer, this is controlled by the board model + } void DLcdPowerHandler::PowerDownLcd() @@ -197,9 +200,13 @@ if(aMode != aInfo.iDisplayMode) { - aInfo.iOffsetToFirstPixel = KCOnfigOffsetToFirstPixel; + + aInfo.iOffsetToFirstPixel = KConfigOffsetToFirstPixel; + aInfo.iIsPalettized = KConfigIsPalettized; - aInfo.iOffsetBetweenLines = KCOnfigOffsetBetweenLines; + + aInfo.iOffsetBetweenLines = iVideoInfo.iSizeInPixels.iWidth*4; //Offset depends on width of framebuffer + aInfo.iBitsPerPixel = KConfigBitsPerPixel; } return KErrNone; @@ -207,8 +214,13 @@ TInt DLcdPowerHandler::AllocateFrameBuffer() { - // Allocate physical RAM for video - TInt vSize = TSyborg::VideoRamSize(); +// Allocate physical RAM for video + + //read width and height of display from board model and allocate size + TInt width = ReadReg(iPortAddr, FB_WIDTH); + TInt height = ReadReg(iPortAddr, FB_HEIGHT); + + TInt vSize = 4*width*height; //*4 as 32bits per pixel NKern::ThreadEnterCS(); TInt r = Epoc::AllocPhysicalRam(vSize,Syborg::VideoRamPhys); @@ -248,11 +260,16 @@ TUint* pV2 = (TUint*)iSecureChunk->LinearAddress(); - iVideoInfo.iSizeInPixels.iWidth = KConfigLcdWidth; - iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight; + //width and height set by reading board model + iVideoInfo.iSizeInPixels.iWidth = width; + iVideoInfo.iSizeInPixels.iHeight = height; + + //offset between lines depends on width of screen + iVideoInfo.iOffsetBetweenLines = width*4; + iVideoInfo.iDisplayMode = KConfigLcdDisplayMode; - iVideoInfo.iOffsetToFirstPixel = KCOnfigOffsetToFirstPixel; - iVideoInfo.iOffsetBetweenLines = KCOnfigOffsetBetweenLines; + iVideoInfo.iOffsetToFirstPixel = KConfigOffsetToFirstPixel; + iVideoInfo.iIsPalettized = KConfigIsPalettized; iVideoInfo.iBitsPerPixel = KConfigBitsPerPixel; iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips; @@ -264,16 +281,6 @@ iSecureVideoInfo = iVideoInfo; iSecureVideoInfo.iVideoAddress = (TInt)pV2; - -#if 0 - WriteReg(iPortAddr, FB_ENABLED, 0); - WriteReg(IPortAddr, FB_INT_MASK, 0); - WriteReg(iPortAddr, FB_BASE, iSecureDisplay ? iSecurevRamPhys : ivRamPhys); - WriteReg(iPortAddr, FB_WIDTH, iVideoInfo.iSizeInPixels.iWidth); - WriteReg(iPortAddr, FB_HEIGHT, iVideoInfo.iSizeInPixels.iHeight); - WriteReg(iPortAddr, FB_BLANK, 0); - WriteReg(iPortAddr, FB_ENABLED, 1); -#endif return KErrNone; } @@ -423,43 +430,6 @@ iPortAddr = KHwBaseClcd; - // !@! -#if 0 - // Map the video RAM - TInt vSize = TSyborg::VideoRamSize(); - ivRamPhys = TSyborg::VideoRamPhys(); - - TInt r = DPlatChunkHw::New(iChunk,ivRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC); - if(r != KErrNone) - return r; - - TUint* pV = (TUint*)iChunk->LinearAddress(); - - iSecurevRamPhys = ivRamPhys + vSize; - TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC); - if(r2 != KErrNone) - return r2; - - TUint* pV2 = (TUint*)iSecureChunk->LinearAddress(); -#endif - - iVideoInfo.iSizeInPixels.iWidth = KConfigLcdWidth; - iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight; - iVideoInfo.iDisplayMode = KConfigLcdDisplayMode; - iVideoInfo.iOffsetToFirstPixel = KCOnfigOffsetToFirstPixel; - iVideoInfo.iOffsetBetweenLines = KCOnfigOffsetBetweenLines; - iVideoInfo.iIsPalettized = KConfigIsPalettized; - iVideoInfo.iBitsPerPixel = KConfigBitsPerPixel; - iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips; - iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips; - iVideoInfo.iIsMono = KConfigIsMono; - // !@! iVideoInfo.iVideoAddress = (TInt)pV; - iVideoInfo.iIsPixelOrderLandscape = KConfigPixelOrderLandscape; - iVideoInfo.iIsPixelOrderRGB = KConfigPixelOrderRGB; - - iSecureVideoInfo = iVideoInfo; - // !@! iSecureVideoInfo.iVideoAddress = (TInt)pV2; - AllocateFrameBuffer(); TInt r = Kern::AddHalEntry(EHalGroupDisplay,DoHalFunction,this); if(r != KErrNone) diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/fb/syborg_fb.h --- a/baseport/syborg/fb/syborg_fb.h Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/fb/syborg_fb.h Tue Apr 06 17:00:22 2010 +0100 @@ -11,6 +11,8 @@ * * Contributors: * +* Accenture Ltd - Syborg framebuffer improvements, now auto determines frame size from board model, performance and memory improvements +* * Description: Minimalistic frame buffer driver * */ @@ -24,24 +26,29 @@ #include #include + _LIT(KLitLcd,"SYBORG_FB"); -const TUint KConfigLcdWidth = 640; -const TUint KConfigLcdHeight = 480; const TInt KConfigLcdWidthInTwips = 9638; const TInt KConfigLcdHeightInTwips = 7370; + const TBool KConfigIsMono = 0; const TBool KConfigIsPalettized = 0; -const TInt KCOnfigOffsetToFirstPixel = 0; + +const TInt KConfigOffsetToFirstPixel = 0; + const TBool KConfigPixelOrderRGB = 0; const TBool KConfigPixelOrderLandscape = 1; const TInt KConfigLcdDisplayMode = 2; -//const TInt KConfigLcdDisplayMode = 1; + + const TInt KConfigLcdNumberOfDisplayModes = 3; const TInt KConfigBitsPerPixel = 24; -const TInt KCOnfigOffsetBetweenLines = 2560; + + + class DLcdPowerHandler : public DPowerHandler { @@ -72,7 +79,7 @@ TInt GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo); TInt SetDisplayMode(TInt aMode); TInt AllocateFrameBuffer(); - + TBool iDisplayOn; DPlatChunkHw* iChunk; DPlatChunkHw* iSecureChunk; @@ -83,7 +90,7 @@ TDfcQue* iDfcQ; TMessageQue iMsgQ; // to prevent a race condition with Power Manager trying to power up/down at the same time TDfc iPowerUpDfc; - TDfc iPowerDownDfc; + TDfc iPowerDownDfc; private: TVideoInfoV01 iVideoInfo; diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/keyboard/syborg_keyboard.h --- a/baseport/syborg/keyboard/syborg_keyboard.h Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/keyboard/syborg_keyboard.h Tue Apr 06 17:00:22 2010 +0100 @@ -144,11 +144,13 @@ /*3c*/ EStdKeyF2, /*3d*/ EStdKeyF3, /*3e*/ EStdKeyF4, - /*3f*/ EStdKeyF5, - - /*40*/ EStdKeyF6, - /*41*/ EStdKeyF7, - /*42*/ EStdKeyF8, + + /*3f*/ EStdKeyDevice0, //EStdKeyF5, SF: Left soft-key [EStdKeyApplication0] + + /*40*/ EStdKeyDevice3, //EStdKeyF6, SF: OK key + /*41*/ EStdKeyDevice1, //EStdKeyF7, SF: Right soft-key + /*42*/ EStdKeyApplication0, //EStdKeyF8, SF Menu key + /*43*/ EStdKeyF9, /*44*/ EStdKeyF10, /*45*/ EStdKeyNull, @@ -161,7 +163,9 @@ /*4c*/ EStdKeyNull, /*4d*/ EStdKeyRightArrow, /*4e*/ EStdKeyNull, - /*4f*/ EStdKeyNull, + + /*4f*/ EStdKeyEnd, + /*50*/ EStdKeyDownArrow, /*51*/ EStdKeyPageDown, diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/keymap/keymap.cpp --- a/baseport/syborg/keymap/keymap.cpp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/keymap/keymap.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -1356,6 +1356,11 @@ {'0', '9'}, {'A', 'Z'}, {EStdKeyF1, EStdKeyDictaphoneRecord}, + + {EStdKeyDevice0,EStdKeyDeviceF}, + {EStdKeyApplication0, EStdKeyApplicationF}, + {EStdKeyYes, EStdKeyDecBrightness}, + }; LOCAL_D const TUint16 convKeyCodes_base[]= @@ -1481,6 +1486,45 @@ EKeyDictaphonePlay, EKeyDictaphoneStop, EKeyDictaphoneRecord, + + + EKeyDevice0, + EKeyDevice1, + EKeyDevice2, + EKeyDevice3, + EKeyDevice4, + EKeyDevice5, + EKeyDevice6, + EKeyDevice7, + EKeyDevice8, + EKeyDevice9, + EKeyDeviceA, + EKeyDeviceB, + EKeyDeviceC, + EKeyDeviceE, + EKeyDeviceE, + EKeyDeviceF, + EKeyApplication0, + EKeyApplication1, + EKeyApplication2, + EKeyApplication3, + EKeyApplication4, + EKeyApplication5, + EKeyApplication6, + EKeyApplication7, + EKeyApplication8, + EKeyApplication9, + EKeyApplicationA, + EKeyApplicationB, + EKeyApplicationC, + EKeyApplicationD, + EKeyApplicationE, + EKeyApplicationF, + EKeyYes, + EKeyNo, + EKeyIncBrightness, + EKeyDecBrightness + }; // caps-lock: this table traps those scanCodes which are affected by caps-lock diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/monitor/monap.mmp --- a/baseport/syborg/monitor/monap.mmp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/monitor/monap.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -22,6 +22,7 @@ TARGET VariantTarget(exmondebug,dll) +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) SYSTEMINCLUDE /epoc32/include/drivers SYSTEMINCLUDE ../serial diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/pointer/pointer_landscape.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/pointer/pointer_landscape.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* Sosco - derived from pointer.mmp +* +* Description: +* epointer.dll for landscape mode +* +*/ + +#include +#include "kernel/kern_ext.mmh" + +TARGET VariantTarget(epointer_landscape,dll) +TARGETTYPE kext +LINKAS epointer.dll + +SYSTEMINCLUDE . +SYSTEMINCLUDE AsspNKernIncludePath + +SOURCEPATH . +SOURCE syborg_pointer.cpp + +//LIBRARY ekern.lib +LIBRARY PlatformLib + +//NOEXPORTLIBRARY + +//DEFFILE ../e32/~/empty.def +//DEFFILE ./~/cmse.def + +//NOSTRICTDEF + +UID 0x100039cf 0x100000db +VENDORID 0x70000001 + +CAPABILITY all + + diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/pointer/pointer_portrait.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/pointer/pointer_portrait.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* Sosco - derived from pointer.mmp +* +* Description: +* epointer.dll for portrait mode +* +*/ + +#include +#include "kernel/kern_ext.mmh" + +MACRO __PORTRAIT_DISPLAY__ + +TARGET VariantTarget(epointer_portrait,dll) +TARGETTYPE kext +LINKAS epointer.dll + +SYSTEMINCLUDE . +SYSTEMINCLUDE AsspNKernIncludePath + +SOURCEPATH . +SOURCE syborg_pointer.cpp + +//LIBRARY ekern.lib +LIBRARY PlatformLib + +//NOEXPORTLIBRARY + +//DEFFILE ../e32/~/empty.def +//DEFFILE ./~/cmse.def + +//NOSTRICTDEF + +UID 0x100039cf 0x100000db +VENDORID 0x70000001 + +CAPABILITY all + + diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/pointer/syborg_pointer.cpp --- a/baseport/syborg/pointer/syborg_pointer.cpp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/pointer/syborg_pointer.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -20,10 +20,29 @@ #include #include "syborg_pointer.h" -TPointerRv::TPointerRv(): - iRxDfc(RxDfc,this,Kern::DfcQue0(),1) + +_LIT(KPointerDfcQNamePre,"PointDFC"); +const TInt KDfcQuePriority = 27; + + + +TPointerRv::TPointerRv() //sosco : +// iRxDfc(RxDfc,this,Kern::DfcQue0(),1) + { __DEBUG_PRINT("TPointerRv::TPointerRv()"); + + + TInt err = Kern::DfcQInit(&iDfcQue, KDfcQuePriority, &KPointerDfcQNamePre); + if (err) + { + __KTRACE_OPT(KPANIC, Kern::Printf("TPointerRv::TPointerRv() Error creating dfcq (%d)", err)); + } + + iRxDfc = new TDfc(RxDfc,this,&iDfcQue,1); + __ASSERT_ALWAYS(iRxDfc!=NULL,Kern::Printf("Failed to create DFC")); + + TInt r = Interrupt::Bind(EIntPointer,Isr,this); if(r != KErrNone) __KTRACE_OPT(KPANIC, Kern::Printf("TPointerRv::TPointerRv() Interrupt::Bind(%d)=%d", @@ -43,7 +62,7 @@ struct TPointerRv::PData* val = &iPDataFifo[iFifoPos]; iFifoPos++; iFifoCount--; - + if (iFifoPos == FIFO_SIZE) iFifoPos = 0; @@ -53,10 +72,10 @@ void TPointerRv::FifoPush(struct TPointerRv::PData* val) { TInt slot; - + if (iFifoCount == FIFO_SIZE) return; - + slot = iFifoPos + iFifoCount; if (slot >= FIFO_SIZE) slot -= FIFO_SIZE; @@ -74,7 +93,7 @@ TInt reg = ReadReg(KHwBaseKmiPointer,POINTER_ID); WriteReg(KHwBaseKmiPointer,POINTER_INT_ENABLE,1); - + TInt r = Kern::AddHalEntry(EHalGroupMouse,DoPointerHalFunction,this); if(r != KErrNone) __KTRACE_OPT(KPANIC, Kern::Printf("TPointerRv::Init3(): Kern::AddHalEntry()=%d", r)); @@ -86,16 +105,24 @@ r = Kern::HalFunction(EHalGroupDisplay, EDisplayHalCurrentModeInfo, (TAny*)&buf, NULL); if(r != KErrNone) __KTRACE_OPT(KPANIC, Kern::Printf("TPointerRv::Init3(): Kern::HalFunction(EDisplayHalCurrentModeInfo)=%d", r)); - + iScreenWidth = videoInfo.iSizeInPixels.iWidth; iScreenHeight = videoInfo.iSizeInPixels.iHeight; iDisplayMode = videoInfo.iDisplayMode; + + iVideoMem = videoInfo.iVideoAddress + videoInfo.iOffsetToFirstPixel; + iOffSetBetweenEachLine = 640; + ix = iy = 0; iXFactor = Fixed(iScreenWidth) / Fixed(0x8000); iYFactor = Fixed(iScreenHeight) / Fixed(0x8000); - + iFifoPos = iFifoCount = 0; + + + iFirstTime= ETrue; + } @@ -108,7 +135,7 @@ // i->ix += pd->x; // i->iy += pd->y; - + i->ix = int(Fixed(pd->x) * i->iXFactor); i->iy = int(Fixed(pd->y) * i->iYFactor); @@ -155,15 +182,98 @@ } fin: + + + i->DisplayPointer(); + + Kern::AddEvent(e); i->iLastBut = pd->but; } + +void TPointerRv::DisplayPointer() +{ + +TUint32 *pMem =0; +TInt k=0; + + if(!iFirstTime) + { + + //restore old pointer position + pMem = (TUint32 *)iVideoMem; + + pMem+= iYtop* iOffSetBetweenEachLine; + pMem+= iXleft; + + + + for(TInt i=0;i<(iYbottom-iYtop);i++) + { + for(TInt j=0;j<(iXright-iXleft);j++) + { + *pMem = iImageStore[k]; + pMem++; + k++; + + } + + pMem+= (iOffSetBetweenEachLine - iXright) + iXleft; + } + } + + iFirstTime = EFalse; + + //10*10 pixel pointer centered around position and check are within allowed bounds of screen + iXleft = ix - 5; + + if(iXleft<0) + iXleft=0; + + iXright = ix + 5; + + if(iXright>iScreenWidth) + iXright = iScreenWidth; + + iYtop = iy - 5; + + if(iYtop<0) + iYtop=0; + + iYbottom = iy +5; + + if(iYbottom> iScreenHeight) + iYbottom=iScreenHeight; + + pMem = (TUint32 *)iVideoMem; + k=0; + + pMem+= iYtop* iOffSetBetweenEachLine; + pMem+= iXleft; + + for(TInt i=0;i<(iYbottom-iYtop);i++) + { + for(TInt j=0;j<(iXright-iXleft);j++) + { + iImageStore[k] = *pMem; + *pMem = 0; + pMem++; + k++; + + } + + pMem+= (iOffSetBetweenEachLine - iXright) + iXleft; + } + +} + + void TPointerRv::RxDfc(TAny* aPtr) { __DEBUG_PRINT("TPointerRv::RxDfc"); - TPointerRv* i = static_cast(aPtr); + TPointerRv* i = static_cast(aPtr); while(i->iFifoCount>0) { struct TPointerRv::PData *pd= i->FifoPop(); @@ -178,19 +288,30 @@ TPointerRv& k = *(TPointerRv*)aPtr; // interrupts are now auto clear - while(ReadReg(KHwBaseKmiPointer, POINTER_FIFO_COUNT)!=0) { + + while(ReadReg(KHwBaseKmiPointer, POINTER_FIFO_COUNT)!=0) + { + + WriteReg(KHwBaseKmiPointer,POINTER_LATCH,1); + // SOSCO: moved to here, as the buffer seems to be running one notch out, + // writing to the pointer latch first seems to return the correct FIFO entry. + struct TPointerRv::PData pd; pd.x = ReadReg(KHwBaseKmiPointer,POINTER_X); pd.y = ReadReg(KHwBaseKmiPointer,POINTER_Y); pd.z = ReadReg(KHwBaseKmiPointer,POINTER_Z); - pd.but = ReadReg(KHwBaseKmiPointer,POINTER_BUTTONS); + pd.but = ReadReg(KHwBaseKmiPointer,POINTER_BUTTONS); k.FifoPush(&pd); - WriteReg(KHwBaseKmiPointer,POINTER_LATCH,0); + +// SOSCO - moved WriteReg(KHwBaseKmiPointer,POINTER_LATCH,1); + } - + // WriteReg(KHwBaseKmiPointer,POINTER_CLEAR_INT,0); - Interrupt::Clear(EIntPointer); - k.iRxDfc.Add(); + Interrupt::Clear(EIntPointer); + + k.iRxDfc->Add(); + } TInt TPointerRv::DoPointerHalFunction(TAny* aThis, TInt aFunction, TAny* a1, TAny* a2) @@ -210,24 +331,28 @@ { kumemput32(a1, (TBool*)&iPointerOn, sizeof(TBool)); break; - } + } case EMouseHalSetMouseState: { + + /* SOSCO - removed, causes platsec error __SECURE_KERNEL( if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD, __PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EMouseHalSetMouseState"))) return KErrPermissionDenied; ); + */ + if(((TBool)a1 == HAL::EMouseState_Visible) && (iPointerOn == (TBool)EFalse)) { iPointerOn=(TBool)ETrue; - } - else if(((TBool)a1 == HAL::EMouseState_Invisible) && (iPointerOn==(TBool)ETrue)) + } + else if(((TBool)a1 == HAL::EMouseState_Invisible) && (iPointerOn==(TBool)ETrue)) { iPointerOn=(TBool)EFalse; - } + } break; - } + } case EMouseHalMouseInfo: { TPckgBuf vPckg; @@ -239,30 +364,38 @@ xyinfo.iOffsetToDisplay.iY = 0; Kern::InfoCopy(*(TDes8*)a1,vPckg); break; - } + } case EMouseHalSetMouseSpeed: { + + /* SOSCO - removed, causes platsec error __SECURE_KERNEL( if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD, __PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EMouseHalSetMouseSpeed"))) return KErrPermissionDenied; ); + */ + // fall thru to NotSupported } case EMouseHalSetMouseAcceleration: { + + /* SOSCO - removed, causes platsec error __SECURE_KERNEL( if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD, __PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EMouseHalSetMouseAcceleration"))) return KErrPermissionDenied; ); + */ + // fall thru to NotSupported } default: { r = KErrNotSupported; break; - } + } } return r; } diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/pointer/syborg_pointer.h --- a/baseport/syborg/pointer/syborg_pointer.h Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/pointer/syborg_pointer.h Tue Apr 06 17:00:22 2010 +0100 @@ -60,16 +60,35 @@ static void RxDfc(TAny* aPtr ); static void Process(TPointerRv *i, struct PData *); - TDfc iRxDfc; + void DisplayPointer(); + + + + //TDfc iRxDfc; + TDfcQue iDfcQue; + TDfc* iRxDfc; + TBool iPointerOn; // cursor visiability TInt iScreenWidth; TInt iScreenHeight; TInt iDisplayMode; + TInt iVideoMem; + TInt iOffSetBetweenEachLine; + + TInt ix,iy; TInt iLastBut; + + TBool iFirstTime; + TInt iXleft; + TInt iXright; + TInt iYtop; + TInt iYbottom; + TInt iImageStore[100]; + public: diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/rom/base_syborg.iby --- a/baseport/syborg/rom/base_syborg.iby Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/rom/base_syborg.iby Tue Apr 06 17:00:22 2010 +0100 @@ -32,7 +32,11 @@ bootbinary= KERNEL_DIR\_PLATFORM_NAME_bootloader_bootrom.bin debugport 0 -romsize=0x2000000 + +// Fixed rom over flow +//romsize=0x2000000 +romsize=0x8000000 + romlinearbase=0x80000000 romalign=0x10 kerneldataaddress=0xC8000000 @@ -64,14 +68,30 @@ // IEEE-mode VFP support extension[VARID]= KERNEL_DIR\DEBUG_DIR\evfp.dll \sys\bin\evfp.dll + +// Either include NGA or Non NGA Framebuffer +#ifdef SYMBIAN_BASE_USE_GCE +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_svpframebuffer.dll \sys\bin\lcd.dll +device[VARID]=KERNEL_DIR\DEBUG_DIR\display.ldd \sys\bin\display0.ldd +#else extension[VARID]= KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_lcd.dll \sys\bin\lcd.dll +#endif + device[VARID]= KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_eserial.pdd \sys\bin\euart1.pdd device[VARID]= KERNEL_DIR\DEBUG_DIR\ecomm.ldd \sys\bin\ecomm.ldd extension[VARID]= KERNEL_DIR\DEBUG_DIR\elocd.ldd \sys\bin\elocd.ldd -extension[VARID]= KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_epointer.dll \sys\bin\epointer.dll + +// Changes allowing us of either portrait or landscape mode +//extension[VARID]= KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_epointer.dll \sys\bin\epointer.dll +#ifdef _PORTRAIT_ +extension[VARID]= KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_epointer_portrait.dll \sys\bin\epointer.dll +#else +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_epointer_landscape.dll \sys\bin\epointer.dll +#endif + extension[VARID]= KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_medint.pdd \sys\bin\medint.pdd extension[VARID]= KERNEL_DIR\DEBUG_DIR\exstart.dll \sys\bin\exstart.dll @@ -80,13 +100,18 @@ extension[VARID]= KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_ekeyb.dll \sys\bin\ekeyb.dll // Kernel pipe -device[VARID]= KERNEL_DIR\DEBUG_DIR\pipelib.ldd \sys\bin\pipelib.ldd + +//device[VARID] =KERNEL_DIR\DEBUG_DIR\pipelib.ldd \sys\bin\pipelib.ldd + // Host Filesystem extension[VARID]= KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_svphostfsdriver.ldd sys\bin\svphostfsdriver.ldd file= KERNEL_DIR\DEBUG_DIR\svphostfsy.fsy sys\bin\svphostfsy.fsy file= KERNEL_DIR\DEBUG_DIR\svphostfs.exe sys\bin\svphostfs.exe -file= KERNEL_DIR\DEBUG_DIR\svphostfsstart.exe sys\bin\sysstart.exe + +// Conflicts with /epoc32/rom/include/core/os/starter.iby +//file= KERNEL_DIR\DEBUG_DIR\svphostfsstart.exe sys\bin\sysstart.exe + // file= KERNEL_DIR\DEBUG_DIR\stdnew.dll sys\bin\stdnew.dll @@ -94,14 +119,36 @@ extension[VARID]= KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_svpsnapdriver.ldd sys\bin\svpsnapdriver.ldd file= KERNEL_DIR\DEBUG_DIR\snapapp.exe sys\bin\snapapp.exe +// Webcamera Driver +device[VARID]= KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_webcamera.pdd sys\bin\webcamera.pdd +device[VARID]= KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_ewebcamera.ldd sys\bin\ewebcamera.ldd +file= KERNEL_DIR\DEBUG_DIR\webcamera_app.exe sys\bin\webcamera_app.exe + // Estart drive mapping setup files. data= EPOCROOT##epoc32\rom\syborg\estart.txt \sys\data\estart.txt define HAL_DLL _PLATFORM_NAME_hal.dll -define ESTART_EXE e32strt.exe + +//define ESTART_EXE e32strt.exe +define ESTART_EXE _PLATFORM_NAME_e32strt.exe // customised ESTART + define KEYMAP_FILE _PLATFORM_NAME_ekdata -#define SCDV_DLL _PLATFORM_NAME_scdv.dll + +file=ABI_DIR\DEBUG_DIR\KEYMAP_FILE.dll \sys\bin\ekdata.dll + +#define SCDV_DLL _generic_scdv.dll #define EUSER_DLL _PLATFORM_NAME_euser.dll +device[VARID] =KERNEL_DIR\DEBUG_DIR\pipelib.ldd \sys\bin\pipelib.ldd + + +device[VARID] =KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_soundsc.pdd \sys\bin\soundsc.pdd +device[VARID] =KERNEL_DIR\DEBUG_DIR\esoundsc.ldd \sys\bin\esoundsc.ldd + +//add sampling profiler +file= KERNEL_DIR\DEBUG_DIR\profiler.exe \sys\bin\profiler.exe +device[VARID] =KERNEL_DIR\DEBUG_DIR\sampler.ldd \sys\bin\sampler.ldd + + #endif // __BASE_SYBORG_IBY__ diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/rom/kernel.iby --- a/baseport/syborg/rom/kernel.iby Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/rom/kernel.iby Tue Apr 06 17:00:22 2010 +0100 @@ -53,12 +53,21 @@ extension[VARID]= \epoc32\release\##KMAIN##\##BUILD##\_##VARIANT##_svphostfsdriver.ldd \sys\bin\svphostfsdriver.ldd file= \epoc32\release\##KMAIN##\##BUILD##\svphostfsy.fsy \sys\bin\svphostfsy.fsy file= \epoc32\release\##KMAIN##\##BUILD##\svphostfs.exe \sys\bin\svphostfs.exe -file= \epoc32\release\##KMAIN##\##BUILD##\svphostfsstart.exe \sys\bin\sysstart.exe + +//file= \epoc32\release\##KMAIN##\##BUILD##\svphostfsstart.exe \sys\bin\sysstart.exe +#define CUSTOM_ESTART +file= \epoc32\release\##KMAIN##\##BUILD##\_##VARIANT##_e32strt.exe sys\bin\estart.exe HEAPMAX (0x10000) + // Snap Driver extension[VARID]= \epoc32\release\##KMAIN##\##BUILD##\_##VARIANT##_svpsnapdriver.ldd \sys\bin\svpsnapdriver.ldd file= \epoc32\release\##KMAIN##\##BUILD##\snapapp.exe \sys\bin\snapapp.exe +// Webcamera Driver +device[VARID]= \epoc32\release\##KMAIN##\##BUILD##\_##VARIANT##_webcamera.PDD \sys\bin\webcamera.PDD +device[VARID]= \epoc32\release\##KMAIN##\##BUILD##\_##VARIANT##_ewebcamera.LDD \sys\bin\ewebcamera.LDD +file= \epoc32\release\##KMAIN##\##BUILD##\webcamera_app.exe \sys\bin\webcamera_app.exe + // Estart data= \epoc32\rom\syborg\ESTART.TXT \sys\data\ESTART.TXT @@ -68,3 +77,7 @@ extension[VARID]= \epoc32\release\##KMAIN##\##BUILD##\_##VARIANT##_MEDINT.PDD \sys\bin\MEDINT.PDD //device[VARID]= \epoc32\release\##KMAIN##\##BUILD##\D_DEBUG.LDD \sys\bin\D_DEBUG.LDD + +device[VARID] = \epoc32\release\##KMAIN##\##BUILD##\_##VARIANT##_soundsc.pdd \sys\bin\soundsc.pdd +device[VARID] = \epoc32\release\##KMAIN##\##BUILD##\esoundsc.ldd \sys\bin\esoundsc.ldd + diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/serial/serial.mmp --- a/baseport/syborg/serial/serial.mmp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/serial/serial.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -21,6 +21,7 @@ TARGET VariantTarget(eserial,pdd) TARGETTYPE pdd +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) SYSTEMINCLUDE /epoc32/include/drivers SYSTEMINCLUDE AsspNKernIncludePath diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/serial/syborg_serial.cpp --- a/baseport/syborg/serial/syborg_serial.cpp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/serial/syborg_serial.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -156,6 +156,10 @@ break; WriteReg(iPortAddr, SERIAL_DATA, r); } + + iLdd->iTxError = KErrNone; + iLdd->iTxCompleteDfc.Add(); + } TUint DCommSyborgSoc::Signals() const diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/bld.inf Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,5 @@ +PRJ_PLATFORMS +ARMV5 + +PRJ_MMPFILES +soundsc.mmp diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/shared_sound.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/shared_sound.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,98 @@ +/* +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* Accenture Ltd +* +* Description: This file is a part of sound driver for Syborg adaptation. +* +*/ + +#ifndef __SYBORGSHARED_SOUND_H__ +#define __SYBORGSHARED_SOUND_H__ + +#include + +#ifdef _ENABLE_SYBORG_AUDIO_DRIVER_DEBUG +#define SYBORG_SOUND_DEBUG(x...) Kern::Printf(x) +#else +#define SYBORG_SOUND_DEBUG(x...) +#endif + +#undef ASSERT +#define ASSERT(x) (x) || (Kern::Printf("Sound.pdd: ASSERTION FAILED: "#x),0); + +#include "virtio_audio.h" +#include "virtio.h" +#include "virtio_audio_defs.h" + +/// @brief defines the maximum size for a single audio data transfer +static const TInt KMaxTransferLength = 128 * 1024; + +namespace VirtIo +{ +class DIoHandler; +} + +class DDriverSyborgSoundScPddFactory; + + +class DDriverSyborgSoundScPdd : public DSoundScPdd, VirtIo::MIoCallback + { +public: + + DDriverSyborgSoundScPdd(DDriverSyborgSoundScPddFactory* aPhysicalDevice, + TInt aUnitType, VirtIo::DIoHandler *aIoHandler, TUint aDataQueueId); + ~DDriverSyborgSoundScPdd(); + TInt DoCreate(); + void GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo); + void Caps(TDes8& aCapsBuf) const; + TInt MaxTransferLen() const; + TInt SetConfig(const TDesC8& aConfigBuf); + TInt SetVolume(TInt aVolume); + TInt StartTransfer(); + TInt TransferData(TUint aTransferID, TLinAddr aLinAddr, TPhysAddr aPhysAddr, TInt aNumBytes); + void StopTransfer(); + TInt PauseTransfer(); + TInt ResumeTransfer(); + TInt PowerUp(); + void PowerDown(); + TInt CustomConfig(TInt aFunction, TAny* aParam); + void SetCaps(); + TDfcQue* DfcQ(); + TDfcQue* DfcQ( TInt aUnit ); + + TInt CalculateBufferTime(TInt aNumBytes); +private: + + // implementation of VirtIo::MIoCallback + virtual TBool VirtIoCallback( VirtIo::MIoHandler& aVirtIoHandler, VirtIo::MQueue& aQueue, + VirtIo::Token aToken, TUint aBytesTransferred ); + +public: + + DDriverSyborgSoundScPddFactory* iPhysicalDevice; + + TInt iUnitType; //Play or Record + + VirtIo::MIoHandler* iIoHandler; + + TUint iDataQueueId; + +private: + + TSoundFormatsSupportedV02 iCaps; + + TCurrentSoundFormatV02 iConfig; + + VirtIo::Audio::DControl* iAudioControl; + + }; + +#endif diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/shared_txsound.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/shared_txsound.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,330 @@ +/* +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* Accenture Ltd +* +* Description: This file is a part of sound driver for Syborg adaptation. +* +*/ + +#include "shared_sound.h" +#include "variant_sound.h" +#include "../specific/syborg.h" + +#include "virtio.h" +#include "virtio_audio.h" +#include "virtio_iohandler.h" + +using namespace VirtIo; + +static TInt GetSampleRate( TSoundRate aRate) + { + switch(aRate) + { + case ESoundRate7350Hz: return 7350; + case ESoundRate8000Hz: return 8000; + case ESoundRate8820Hz: return 8820; + case ESoundRate9600Hz: return 9600; + case ESoundRate11025Hz: return 11025; + case ESoundRate12000Hz: return 12000; + case ESoundRate14700Hz: return 14700; + case ESoundRate16000Hz: return 16000; + case ESoundRate22050Hz: return 22050; + case ESoundRate24000Hz: return 24000; + case ESoundRate29400Hz: return 29400; + case ESoundRate32000Hz: return 32000; + case ESoundRate44100Hz: return 44100; + case ESoundRate48000Hz: return 48000; + } + return KErrNotFound; + } + +static TInt GetSoundEncoding( TSoundEncoding aV ) + { + switch (aV) + { + case ESoundEncoding8BitPCM: return Audio::EFormatS8; + case ESoundEncoding16BitPCM: return Audio::EFormatS16; + case ESoundEncoding24BitPCM: break; // not supported + } + return -KErrNotFound; + } +static TInt GetChannels( TInt aV ) + { + switch (aV) + { + case KSoundMonoChannel: return 1; + case KSoundStereoChannel: return 2; + } + return KErrNotFound; + } + +DDriverSyborgSoundScPdd::DDriverSyborgSoundScPdd(DDriverSyborgSoundScPddFactory* aPhysicalDevice, + TInt aUnitType, VirtIo::DIoHandler* aIoHandler, TUint aDataQueueId ) + : iPhysicalDevice(aPhysicalDevice), iUnitType(aUnitType), iIoHandler( aIoHandler ), iDataQueueId( aDataQueueId ) + { + } + +DDriverSyborgSoundScPdd::~DDriverSyborgSoundScPdd() + { + SYBORG_SOUND_DEBUG("~DDriverSyborgSoundScPdd()"); + iIoHandler->UnregisterClient( this ); + delete iAudioControl; + SYBORG_SOUND_DEBUG("~DDriverSyborgSoundScPdd() - done"); + } + +TInt DDriverSyborgSoundScPdd::DoCreate() + { + SetCaps(); + + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::DoCreate TxPdd"); + + SYBORG_SOUND_DEBUG("Registering with IOHandler %x", iIoHandler ); + iIoHandler->RegisterClient( this ); + SYBORG_SOUND_DEBUG("Registered with IoHandler... Done %x", iIoHandler); + + iAudioControl = new Audio::DControl( *iIoHandler, iDataQueueId ); + iAudioControl->Construct(); + + return KErrNone; + } + +void DDriverSyborgSoundScPdd::GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo) + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::GetChunkCreateInfo TxPdd"); + + aChunkCreateInfo.iType = TChunkCreateInfo::ESharedKernelMultiple; + aChunkCreateInfo.iMapAttr = EMapAttrFullyBlocking; // No caching + aChunkCreateInfo.iOwnsMemory = ETrue; // Using RAM pages + aChunkCreateInfo.iDestroyedDfc = NULL; // No chunk destroy DFC + } + +void DDriverSyborgSoundScPdd::Caps(TDes8& aCapsBuf) const + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::Caps TxPdd"); + + // Fill the structure with zeros in case it is a newer version than we know about + aCapsBuf.FillZ(aCapsBuf.MaxLength()); + + // And copy the capabilities into the packaged structure + TPtrC8 ptr((const TUint8*) &iCaps, sizeof(iCaps)); + aCapsBuf = ptr.Left(Min(ptr.Length(), aCapsBuf.MaxLength())); + } + +TInt DDriverSyborgSoundScPdd::SetConfig(const TDesC8& aConfigBuf) + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::SetConfig TxPdd"); + + // Read the new configuration from the LDD + TCurrentSoundFormatV02 config; + TPtr8 ptr((TUint8*) &config, sizeof(config)); + Kern::InfoCopy(ptr, aConfigBuf); + + TInt channels = GetChannels(config.iChannels); + Audio::FormatId encoding = static_cast( GetSoundEncoding(config.iEncoding) ); + TInt freq = GetSampleRate(config.iRate); + Audio::StreamDirection direction = static_cast( + (iUnitType == KSoundScRxUnit0)?Audio::EDirectionRecord + :(iUnitType == KSoundScTxUnit0)?Audio::EDirectionPlayback:-1 ); + + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::SetConfig c %x, e %x, f %x, d %x", + channels, encoding, freq, direction ); + + if ( (channels < 0 ) + || ( encoding < 0 ) + || ( freq < 0 ) + || ( direction < 0 ) + ) + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::SetConfig failed"); + return KErrArgument; + } + + TInt st = iAudioControl->Setup( direction, channels, encoding, freq ); + if (st !=KErrNone) + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::SetConfig failed %d", st); + return st; + } + + iConfig = config; + + return KErrNone; + } + + +TInt DDriverSyborgSoundScPdd::SetVolume(TInt aVolume) + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::Setvolume TxPdd"); + + return KErrNone; + } + + +TInt DDriverSyborgSoundScPdd::StartTransfer() + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::starttransfer TxPdd S"); + iAudioControl->SendCommand( Audio::DControl::ERun ); + return KErrNone; + } + + +TInt DDriverSyborgSoundScPdd::CalculateBufferTime(TInt aNumBytes) + { + TUint samplerate=GetSampleRate( iConfig.iRate ); + + // integer division by number of channels + aNumBytes /= iConfig.iChannels; + + // integer division by bytes per sample + switch(iConfig.iEncoding) + { + case ESoundEncoding8BitPCM: break; + case ESoundEncoding16BitPCM: aNumBytes /= 2; break; + case ESoundEncoding24BitPCM: aNumBytes /= 3; break; + } + + return (aNumBytes * 1000) / samplerate; //return time in milliseconds + } + +TInt DDriverSyborgSoundScPdd::TransferData(TUint aTransferID, TLinAddr aLinAddr, TPhysAddr aPhysAddr, TInt aNumBytes) + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::TransferData unit %x aTId=%x, linAddr=%x,phAddr=%x,len=%x", + iUnitType, aTransferID, aLinAddr, aPhysAddr, aNumBytes); + + iAudioControl->SendDataBuffer( + reinterpret_cast( aLinAddr ), aNumBytes, reinterpret_cast( aTransferID ) ); + + return KErrNone; + } + +void DDriverSyborgSoundScPdd::StopTransfer() + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::stoptransfer TxPdd"); + + iAudioControl->SendCommand( Audio::DControl::EStop ); + } + + +TInt DDriverSyborgSoundScPdd::PauseTransfer() + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::pausetransfer TxPdd"); + iAudioControl->SendCommand( Audio::DControl::EPause ); + return KErrNone; + } + + +TInt DDriverSyborgSoundScPdd::ResumeTransfer() + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::resumetransfer TxPdd"); + iAudioControl->SendCommand( Audio::DControl::EResume ); + return KErrNone; + } + +TInt DDriverSyborgSoundScPdd::PowerUp() + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::PowerUp TxPdd"); + return KErrNone; + } + +void DDriverSyborgSoundScPdd::PowerDown() + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::Powerdown TxPdd"); + } + +TInt DDriverSyborgSoundScPdd::CustomConfig(TInt /*aFunction*/,TAny* /*aParam*/) + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::CustomConfig TxPdd"); + return KErrNotSupported; + } + +TBool DDriverSyborgSoundScPdd::VirtIoCallback( MIoHandler& aVirtIoHandler, MQueue& aQueue, + Token aToken, TUint aBytesTransferred ) + { + if ( &aQueue != &iAudioControl->DataQueue() ) + { return ETrue; } + + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::VirtIoCallback t%x, s%x", aToken, aBytesTransferred); + + if ( iCaps.iDirection == ESoundDirPlayback ) + { + Ldd()->PlayCallback( (TUint) aToken, KErrNone, aBytesTransferred ); + } + else + { + Ldd()->RecordCallback( (TUint) aToken, KErrNone, aBytesTransferred ); + } + + return EFalse; // cannot process any more buffers in this go due to a bug in LDD? + } + +TDfcQue*DDriverSyborgSoundScPdd::DfcQ() + { + return iPhysicalDevice->iDfcQ; + } + +TDfcQue*DDriverSyborgSoundScPdd::DfcQ( TInt /* aUinit */ ) + { + return iPhysicalDevice->iDfcQ; + } + + +TInt DDriverSyborgSoundScPdd::MaxTransferLen() const + { + return KMaxTransferLength; + } + + +void DDriverSyborgSoundScPdd::SetCaps() + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::SetCaps TxPdd"); + + if(iUnitType == KSoundScTxUnit0) + { + // The data transfer direction for this unit is play + iCaps.iDirection = ESoundDirPlayback; + } + else if(iUnitType == KSoundScRxUnit0) + { + // The data transfer direction for this unit is play + iCaps.iDirection = ESoundDirRecord; + } + + // This unit supports both mono and stereo + iCaps.iChannels = (KSoundMonoChannel | KSoundStereoChannel); + + // This unit supports only some of the sample rates offered by Symbian OS + iCaps.iRates = (KSoundRate8000Hz | KSoundRate11025Hz | KSoundRate12000Hz | KSoundRate16000Hz | + KSoundRate22050Hz | KSoundRate24000Hz | KSoundRate32000Hz | KSoundRate44100Hz | + KSoundRate48000Hz); + + // This unit only supports 16bit PCM encoding + iCaps.iEncodings = KSoundEncoding16BitPCM; + + // This unit only supports interleaved data format when playing stereo; that is, a PCM data + // stream where the left and right channel samples are interleaved as L-R-L-R-L-R etc. + iCaps.iDataFormats = KSoundDataFormatInterleaved; + + // The iRequestMinSize member is named badly. It is actually the value of which the length samples + // must be a multiple of. ie. The sample length % iRequestMinSize must == 0. This value must always + // be a power of 2 + iCaps.iRequestMinSize = 4; + + // The logarithm to base 2 of the alignment required for request arguments. DMA requests must be + // aligned to a 32 bit boundary + iCaps.iRequestAlignment = 2; + + // This unit is not capable of detecting changes in hardware configuration + iCaps.iHwConfigNotificationSupport = EFalse; + } + + + + diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/soundsc.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/soundsc.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,41 @@ +/* +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* Accenture Ltd +* +* Description: This file is a part of sound driver for Syborg adaptation. +* +*/ + +#include "../variant.mmh" +#include "kernel/kern_ext.mmh" + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) +SYSTEMINCLUDE /epoc32/include/drivers + + +TARGET VariantTarget(soundsc,pdd) +TARGETTYPE pdd +ROMTARGET soundsc.pdd + +SYSTEMINCLUDE . + +SOURCE shared_txsound.cpp +SOURCE variant_sound.cpp +SOURCE virtio.cpp +SOURCE virtio_io.cpp +SOURCE virtio_iohandler.cpp +SOURCE virtio_queue.cpp +SOURCE virtio_audio.cpp + +LIBRARY PlatformLib + +CAPABILITY all +EPOCALLOWDLLDATA diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/variant_sound.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/variant_sound.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,166 @@ +/* +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* Accenture Ltd +* +* Description: This file is a part of sound driver for Syborg adaptation. +* +*/ + +#include "variant_sound.h" +#include "virtio_iohandler.h" +#include "../specific/syborg.h" + +_LIT(KSoundScPddName, "SoundSc.Syborg"); + +DECLARE_STANDARD_PDD() + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory created\n"); + return new DDriverSyborgSoundScPddFactory; + } + + +DDriverSyborgSoundScPddFactory::DDriverSyborgSoundScPddFactory() + { + iUnitsMask = ((1 << KSoundScTxUnit0) | (1 << KSoundScRxUnit0)); + + iVersion = RSoundSc::VersionRequired(); + } + + +TInt DDriverSyborgSoundScPddFactory::Install() + { + _LIT(KAudioDFC, "AUDIO DFC"); + + // LDD driver is going to use the same queue. + TInt r = Kern::DynamicDfcQCreate(iDfcQ, KAudioDfcQueuePriority, KAudioDFC); + + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::PDD install"); + + if(r!=KErrNone) + { + SYBORG_SOUND_DEBUG("Creating audio DFC failed %d",r); + return r; + } + // All PDD factories must have a unique name + r = SetName(&KSoundScPddName); + if (r!=KErrNone) + { + SYBORG_SOUND_DEBUG("Setting name %x",r); + return r; + } + iIoHandler = new VirtIo::DIoHandler( + (TAny*)KHwSVPAudioDevice, + EIntAudio0, + iDfcQ ); + + if (iIoHandler == NULL) + { + iDfcQ->Destroy(); + return KErrNoMemory; + } + + SYBORG_SOUND_DEBUG("Constructing IoHandler"); + + r = iIoHandler->Construct(); + + if ( r != KErrNone) + { + iDfcQ->Destroy(); + delete iIoHandler; + } + + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::PDD installed"); + + return r; + } + +DDriverSyborgSoundScPddFactory::~DDriverSyborgSoundScPddFactory() + { + if (iIoHandler) + { + delete iIoHandler; + iIoHandler = NULL; + } + if (iDfcQ) + iDfcQ->Destroy(); + } + + +void DDriverSyborgSoundScPddFactory::GetCaps(TDes8& /*aDes*/) const + { + } + + +TInt DDriverSyborgSoundScPddFactory::Validate(TInt aUnit, const TDesC8* /*aInfo*/, const TVersion& aVer) + { + // Check that the version requested is less than or equal to the version of this PDD + if (!Kern::QueryVersionSupported(RSoundSc::VersionRequired(), aVer)) + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::Validate KErrNotSup1"); + return KErrNotSupported; + } + + // Check the unit number specifies either playback or recording + if ((aUnit != KSoundScTxUnit0) && (aUnit != KSoundScRxUnit0)) + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::Validate KErrNotSup2"); + return KErrNotSupported; + } + + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::Validate KErrNone"); + return KErrNone; + } + +TInt DDriverSyborgSoundScPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/) + { + + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::PDD create aUnit %d TxUnitId %d", aUnit, KSoundScTxUnit0); + + // Assume failure + TInt r = KErrNoMemory; + aChannel = NULL; + + + DDriverSyborgSoundScPdd* pTxD = new DDriverSyborgSoundScPdd( this, aUnit, + iIoHandler, aUnit == KSoundScTxUnit0?1:2 ); + + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::TxPdd %x", pTxD); + + if (pTxD) + { + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::TxPdd2 %x", pTxD); + + r = pTxD->DoCreate(); + + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::Create ret %d", r); + + } + + // If everything succeeded, save a pointer to the PDD. This should only be done if DoCreate() succeeded, + // as some LDDs have been known to access this pointer even if Create() returns an error! + if (r == KErrNone) + { + aChannel = pTxD; + SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::TxPdd set AChannel %x", aChannel); + } + else + { + delete pTxD; + } + + return r; + } + + +VirtIo::MIoHandler* DDriverSyborgSoundScPddFactory::IoHandler() + { + return iIoHandler; + } diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/variant_sound.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/variant_sound.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,46 @@ +/* +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* Accenture Ltd +* +* Description: This file is a part of sound driver for Syborg adaptation. +* +*/ + +#ifndef __SYBORGVARIANT_SOUND_H__ +#define __SYBORGVARIANT_SOUND_H__ + +#include "shared_sound.h" + +static const TUint KAudioDfcQueuePriority = 28; + +class DDriverSyborgSoundScPddFactory : public DPhysicalDevice + { +public: + + DDriverSyborgSoundScPddFactory(); + ~DDriverSyborgSoundScPddFactory(); + TInt Install(); + void GetCaps(TDes8 &aDes) const; + TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion &aVer); + TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer); + + VirtIo::MIoHandler* IoHandler(); + +public: + + /** The DFC queue to be used by both the LDD and the PDD to serialise access to the PDD */ + TDynamicDfcQue* iDfcQ; + + VirtIo::DIoHandler *iIoHandler; + + }; + +#endif diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/virtio.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/virtio.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,58 @@ +/* +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Accenture Ltd +* +* Contributors: +* +* Description: This file is a part of sound driver for Syborg adaptation. +* +*/ + +#include "virtio.h" + +namespace VirtIo +{ + +#define MIN(x,y) (((x)<=(y))?(x):(y)) +#define INVALID_PHYSADDR(x) ((x)==TPhysAddr(-1)) + +TInt LinearToSGL( TAny* aVirtual, TUint aSize, TAddrLen aSGL[], TUint& aSGLCount ) + { + const TUint pageSize = Kern::RoundToPageSize(1); + TUint8* virtAddr = reinterpret_cast( aVirtual ); + TPhysAddr physAddr = Epoc::LinearToPhysical( TLinAddr(virtAddr) ); + if (INVALID_PHYSADDR(physAddr)) + { return KErrArgument; } + TUint sglLimit = aSGLCount; + aSGLCount = 0; + TUint left = aSize; + while (left) + { + TPhysAddr startPhysAddr = physAddr; + TUint8* startVirtAddr = virtAddr; + while ( (left) + && ( Epoc::LinearToPhysical( TLinAddr(virtAddr) ) == physAddr ) ) + { + TUint size = MIN(left, pageSize); + physAddr += size; + virtAddr += size; + left -= size; + } + if (INVALID_PHYSADDR(physAddr)) + { return KErrArgument; } + if ((aSGL) && (aSGLCount MIo that deals with basic io space access +///
  • MQueue that represents a device's transaction queue, which is usually more then one per device +///
  • MIoHandler that represents a device, takes care of resource management, device initialisation and MIo and MQueue derived objects' lifetime. +/// +/// @p The idea is that MIo, MQueue and MIoHandler comes as a specific set. On top of which it is possible to build various drivers (e.g. Audio or Ethernet) that are agnostic to these virtio specifics (e.g. flat device tree or full PCI). +/// +/// Currently the implementation is not multithread safe. The assumption is that all the routines are driven from a single DFC. + +#include "virtio_defs.h" + +#include +#include + + +#ifdef _ENABLE_SYBORG_VIRTIO_DEBUG +#define SYBORG_VIRTIO_DEBUG(x...) Kern::Printf(x) +#else +#define SYBORG_VIRTIO_DEBUG(x...) +#endif + +#undef ASSERT +#define ASSERT(x) (x) || (Kern::Printf("VirtIo: ASSERTION FAILED: "#x),0); + + +namespace VirtIo +{ + +/// @brief type of a buffer token. +typedef TAny* Token; + +/// @brief represents a virtual queue's API. +/// +class MQueue + { +public: + + /// @brief Adds a buffer at the end of the queue + /// + /// @param aScatterList - physical address scatter list + /// @param aOutNum - number of scatter buffers to be sent to the device + /// @param aInNum - number of scatter buffers to be received from the device (starting at aOutNum index of scatter list) + /// @param aToken - a value associated with buffer to be returned by getBuf or used with detachBuf + virtual TInt AddBuf( const TAddrLen aScatterList[], TUint32 aOutNum, + TUint32 aInNum, Token aToken) = 0; + + /// @brief Returns buffer associated with the least recent completed transaction + /// @return transaction's Token with \a len set to reflect amount of processed bytes or + /// 0 if no completed transaction was found. + virtual Token GetBuf( TUint& len ) = 0; + + /// @brief Posts queued buffers to the device + virtual void Sync() = 0; + + /// @brief Cancels a specified buffer (if it is not yet posted) + /// To be used at shutdown + virtual TInt DetachBuf( Token aToken ) = 0; + + /// @brief reenable callbacks + /// @return ETrue - callbacks reenabled, EFalse - callbacks not reenabled as there are pending buffers in + /// the DQueue. + virtual TBool Restart() = 0; + + /// @brief returns number of buffers that are posted to the DQueue + /// but not yet completed + virtual TInt Processing() = 0; + + /// @brief returns number of times the GetBuf function could be called returning a buffer + virtual TInt Completed() = 0; + + /// Returns Id of the queue + virtual TUint Id() = 0; + + }; + + +/// @brief API wrapping the VirtIo IO space access. +class MIo + { +public: + virtual void SetQueueBase( TUint aId, TAny* iDescRegion ) = 0; + virtual TAny* GetQueueBase( TUint aId ) = 0; + virtual void PostQueue( TUint aId ) = 0; + virtual void GetDeviceIds( TUint32 &aPeripheralId, TUint32 &aDeviceId ) = 0; + virtual TUint GetQueueCount( TUint aQId ) = 0; + virtual TBool EnableInterrupt( TBool aEnable ) = 0; + virtual void SetStatus( TUint status ) = 0; + virtual void ClearInteruptStatus() = 0; + virtual TBool InteruptStatus() = 0; + + }; + + +class MIoCallback; + +/// @brief represents a VirtIo device's API. +/// +/// An API for a handler that takes care of resources, state and asyncrhonous communication of a VirtIo device. Allocates Queues. +class MIoHandler + { +public: + /// returns one of the device's queues. + virtual MQueue& Queue( TUint aId ) = 0; + + /// registers a client for buffer notifications. + virtual void RegisterClient( MIoCallback* aListener ) = 0; + + /// unregisters a client for buffer notifications. + virtual void UnregisterClient( MIoCallback* aListener ) = 0; + }; + +/// an interface for a MIoHandler's client to implement. +class MIoCallback + { +public: + /// Notifies MIoHandler's client that that a buffer processing has been completed. + /// + /// @return EFalse to defer subsequent buffer processing in the same callback. + virtual TBool VirtIoCallback( + MIoHandler& aVirtIoHandler, MQueue& aQueue, + Token aToken, TUint aBytesTransferred ) = 0; + }; + +/// @brief turns virtual address range into a phys scatter gather list +/// +/// If virtual buffer contains a linear buffer then the +/// function will create one SGL entry. +/// +/// If function is called with aSGL=0 then it will count the linear physical +/// fragments the buffer is build of. +/// +/// +/// @return KErrArgument if the virtual buffer contains nonconvertible addresses) +TInt LinearToSGL( TAny* aLinear, TUint aSize, TAddrLen aSGL[], TUint& aSGLCount ); + +} + + +#endif diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/virtio_audio.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/virtio_audio.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,158 @@ +/* +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Accenture Ltd +* +* Contributors: +* +* Description: This file is a part of sound driver for Syborg adaptation. +* +*/ + +#include "virtio_audio.h" + +namespace VirtIo +{ +namespace Audio +{ + +DControl::~DControl() + { + if (iCmdMem) + { Kern::Free( iCmdMem ); } + } + +TInt DControl::Construct() + { + TUint cmdSize = sizeof(iCmd[0])*KCmdMaxBufCount; + TUint size = cmdSize + sizeof(*iBufferInfo); + // as we are going to align the allocated memory + // we add extra alignment size minus 1 + iCmdMem = reinterpret_cast( Kern::Alloc( size + sizeof(iCmd[0])-1 ) ); + if (!iCmdMem) + { return KErrNoMemory; } + + // let us align the memory address + // note: sizeof(iCmd[0]) is a power of 2 + ASSERT( sizeof(iCmd[0]) == POW2ALIGN(sizeof(iCmd[0])) ); + TUint8* alignedMem = iCmdMem + + ( (-(TUint32)iCmdMem)&(sizeof(iCmd[0])-1) ); // adding missing amount of bytes + + iCmd = reinterpret_cast( alignedMem ); + iBufferInfo = reinterpret_cast( alignedMem + cmdSize ); + + for (TUint i = 0; i< KCmdMaxBufCount; ++i) + { + iCmd[i].iStream = iDataQueueId - 1; + } + iCmd[0].iCommand = Audio::ECmdSetEndian; + iCmd[1].iCommand = Audio::ECmdSetChannels; + iCmd[2].iCommand = Audio::ECmdSetFormat; + iCmd[3].iCommand = Audio::ECmdSetFrequency; + iCmd[4].iCommand = Audio::ECmdInit; + iCmd[5].iCommand = Audio::ECmdRun; + iCmd[5].iArg = Audio::EDoRun; //start stream + iCmd[6].iCommand = Audio::ECmdRun; + iCmd[6].iArg = Audio::EDoStop; //stop stream + iCmd[7].iCommand = Audio::ECmdRun; + iCmd[7].iArg = Audio::EDoStop; //kind of pause + iCmd[8].iCommand = Audio::ECmdRun; + iCmd[8].iArg = Audio::EDoRun; //kind of resume + return KErrNone; + } + +TInt DControl::Setup( StreamDirection aDirection, TInt aChannelNum, + FormatId aFormat, TInt aFreq) + { + iCmd[1].iArg = aChannelNum; + iCmd[2].iArg = aFormat; + iCmd[3].iArg = aFreq; + iCmd[4].iArg = iDirection = aDirection; + AddCommand(&iCmd[0],(Token)0); + AddCommand(&iCmd[1],(Token)1); + AddCommand(&iCmd[2],(Token)2); + AddCommand(&iCmd[3],(Token)3); + AddCommand(&iCmd[4],(Token)4, iBufferInfo, sizeof(*iBufferInfo) ); + ControlQueue().Sync(); + return KErrNone; + } + +void DControl::AddCommand( TCommandPadded* aCmd, Token aToken ) + { + TAddrLen list; + list.iLen = sizeof(TCommand); + list.iAddr = Epoc::LinearToPhysical((TUint32)aCmd); + SYBORG_VIRTIO_DEBUG("AddCommand %x %x %x", aCmd->iCommand, aCmd->iStream, aCmd->iArg); + ControlQueue().AddBuf(&list, 1, 0, aToken ); + } + +void DControl::AddCommand( TCommandPadded* aCmd, Token aToken, + TAny* aMem, TUint aSize ) + { + TAddrLen list[2]; + list[0].iLen = sizeof(TCommand); + list[0].iAddr = Epoc::LinearToPhysical((TUint32)aCmd); + list[1].iLen = aSize; + list[1].iAddr = Epoc::LinearToPhysical((TUint32)aMem); + ControlQueue().AddBuf(list, 1, 1, aToken ); + } + + +// Waits until device processes all pending requests +// there would be no need to have it here at all +// if there was no bug in qemu: +// once you send stop command the buffers processing stops... but the buffers are never returned. + +void DControl::WaitForCompletion() + { + SYBORG_VIRTIO_DEBUG("DControl::WaitForCompletion : {"); + + TInt st = Kern::PollingWait( &DControl::CheckProcessing, this, 10, 100 ); + ASSERT ( (st == KErrNone) && "Polling problem" ) + + SYBORG_VIRTIO_DEBUG("DControlWaitForCompletion : }"); + } + +TBool DControl::CheckProcessing( TAny* aSelf ) + { + DControl* self = reinterpret_cast( aSelf ); + return self->DataQueue().Processing() == 0; + } + +void DControl::AddCommand( Command aCmd ) + { + TUint idx = aCmd; + if (aCmd == EStop) + { + // due to bug on qemu's side we need to stop sending buffers + // and wait for all pending buffers to get filled... + WaitForCompletion(); + } + AddCommand(&iCmd[idx], (Token)idx ); + } + +TInt DControl::SendDataBuffer( TAny* virtaulAddr, TUint aSize, Token aToken ) + { + TAddrLen sgl[KMaxSGLItemCountPerAudioBuffer]; + TUint sglCount = KMaxSGLItemCountPerAudioBuffer; + TInt st = LinearToSGL(virtaulAddr, aSize, sgl, sglCount ); + ASSERT( st != KErrNoMemory ); // failure means our fixed lenght sgl table is too small + if (st!=KErrNone) + { return st; } + st = DataQueue().AddBuf( sgl, + iDirection == EDirectionPlayback ? sglCount : 0, + iDirection == EDirectionRecord ? sglCount : 0, + aToken ); + if (st!=KErrNone) + { return st; } + DataQueue().Sync(); + return KErrNone; + } + + +} // namespace Audio +} // namespace VirtIo diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/virtio_audio.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/virtio_audio.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,103 @@ +/* +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Accenture Ltd +* +* Contributors: +* +* Description: This file is a part of sound driver for Syborg adaptation. +* +*/ + +#ifndef VIRTIO_AUDIO_H +#define VIRTIO_AUDIO_H + +#include "virtio_audio_defs.h" +#include "virtio_defs.h" +#include "virtio.h" + +#include + +namespace VirtIo +{ + +namespace Audio +{ + +/// Encapsulates routines that affect VirtIo Audio device's Stream. +/// DControl object may share ioHandler with other DControl objects. +/// especially Control Queue. +class DControl : public DBase + { + static const TUint KCmdMaxBufCount = 8; + static const TUint KControlQueueId = 0; +public: + enum Command { ERun = 5, EStop, EPause, EResume }; + + DControl( VirtIo::MIoHandler& aIoHandler, TUint32 aDataQueueId ) + : iIoHandler( aIoHandler ), iDataQueueId( aDataQueueId) + {} + + ~DControl(); + + TInt Construct(); + + /// sets up stream parameters. + TInt Setup( StreamDirection aDirection, TInt aChannelNum, + FormatId aFormat, TInt aFreq ); + + /// @brief posts a data buffer. + /// + /// The virtaulAddr is going to be turned into + /// a physical address scatter gather list. + TInt SendDataBuffer( TAny* virtaulAddr, TUint aSize, Token aToken ); + + /// Sends a specific command + void SendCommand( Command aCmd ) + { AddCommand( aCmd ); ControlQueue().Sync(); } + + /// Return Data Queue of the stream. + MQueue& DataQueue() + { return iIoHandler.Queue(iDataQueueId); } + + /// Returns Control Queue of the associated device. + MQueue& ControlQueue() + { return iIoHandler.Queue(KControlQueueId); } + +private: + // size of this struct needs to be power2 aligned + // we extend original TCommand with padding to ensure this + struct TCommandPadded: public TCommand + { + static const TUint KPaddingSize = POW2ALIGN(sizeof(TCommand))-sizeof(TCommand); + TUint8 iPadding[KPaddingSize]; + }; + + void AddCommand( TCommandPadded* aCmd, Token aToken ); + + void AddCommand( TCommandPadded* aCmd, Token aToken, TAny* mem, TUint size ); + + void AddCommand( Command aCmd ); + + void WaitForCompletion(); + static TBool CheckProcessing( TAny* aSelf ); + + VirtIo::MIoHandler& iIoHandler; + TUint iDataQueueId; + + TUint8* iCmdMem; // managed + TCommandPadded* iCmd; // unmanaged + TBufferInfo* iBufferInfo; // unmanaged + + StreamDirection iDirection; + }; + +} // namespace Audio +} // namespace VirtIo + + +#endif diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/virtio_audio_defs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/virtio_audio_defs.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,85 @@ +/* +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Accenture Ltd +* +* Contributors: +* +* Description: This file is a part of sound driver for Syborg adaptation. +* +*/ + +#ifndef VIRTIO_AUDIO_DEFS_H //x +#define VIRTIO_AUDIO_DEFS_H + +#include + +/// @file virtio_audio_defs.h +/// most of definitions here come from VirtIo Audio spec +/// and was made compatible to the qemu backend (which means diverged from spec) + +namespace VirtIo +{ +namespace Audio +{ + +static const TUint KMaxSGLItemCountPerAudioBuffer = 64; + +enum CommandId + { + ECmdSetEndian=1, + ECmdSetChannels=2, + ECmdSetFormat=3, + ECmdSetFrequency=4, + ECmdInit=5, + ECmdRun=6 + }; + +enum FormatId + { + EFormatU8=0, + EFormatS8=1, + EFormatU16=2, + EFormatS16=3, + EFormatU32=4, + EFormatS32=5 + }; + +enum RunType + { + EDoStop = 0, + EDoRun = 1 + }; + +// note the values are opposite to what spec says +enum StreamDirection + { + EDirectionPlayback = 0, + EDirectionRecord = 1 + }; + +struct TCommand + { + TUint32 iCommand; + TUint32 iStream; + TUint32 iArg; + }; + +struct TBufferInfo + { + TUint32 bufferSize; + TUint32 iA[3]; // not really documented + }; + +static const TUint32 KVirtIoPeripheralId = 0xc51d000a; +static const TUint32 KVirtIoDeviceId = 0xffff; + +} // namespace Audio +} // namespace VirtIo + +#endif + diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/virtio_defs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/virtio_defs.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,117 @@ +/* +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Accenture Ltd +* +* Contributors: +* +* Description: This file is a part of sound driver for Syborg adaptation. +* +*/ + +#ifndef VIRTIO_DEFS_H +#define VIRTIO_DEFS_H + +#include +#include // fot TPhysAddr + +/// @file virtio_defs.h +/// most of definitions here come from VirtIo spec +/// and was made compatible to the qemu backend (which means diverged from spec) + +namespace VirtIo +{ + +#define POW2ALIGN1(x) ((x)|((x)>>1)) +#define POW2ALIGN2(x) ((x)|((x)>>2)) +#define POW2ALIGN4(x) ((x)|((x)>>4)) +#define POW2ALIGN8(x) ((x)|((x)>>8)) +#define POW2ALIGN16(x) ((x)|((x)>>16)) + +///@brief Alignes \a x to the closest bigger or equal power2 value +#define POW2ALIGN(x) (POW2ALIGN16(POW2ALIGN8(POW2ALIGN4(POW2ALIGN2(POW2ALIGN1((x)-1)))))+1) + +static const TUint KVirtIoAlignment = 0x1000; + +enum + { + EStatusReset = 0, + EStatusAcknowledge = 1, + EStatusDriverFound = 2, + EStatusDriverInitialised = 4, + EStatusFailed = 0x80 + }; + +enum + { + EIoID = 0, + EIoDevType = 1, + EIoHostFeatures = 2, + EIoGuestFeatures = 3, + EIoQueueBase = 4, + EIoQueueSize = 5, + EIoQueueSelect = 6, + EIoQueueNotify = 7, + EIoStatus = 8, + EIoInterruptEnable = 9, + EIoInterruptStatus = 10 + }; + +struct TRingDesc + { + enum + { + EFlagNext = 1, + EFlagWrite = 2 + }; + + TUint64 iAddr; // physical address + TUint32 iLen; + TUint16 iFlags; + TUint16 iNext; + }; + +struct TRingAvail + { + enum { EFlagInhibitNotifications = 1 }; + TUint16 iFlags; + TUint16 iIdx; + TUint16 iRing[1]; + }; + +struct TRingUsed + { + enum { EFlagInhibitNotifications = 1 }; + TUint16 iFlags; + TUint16 iIdx; + struct + { + TUint32 iId; + TUint32 iLen; + } iRing[1]; + }; + +/// @brief Represents element of scatter gather list +struct TAddrLen + { + TPhysAddr iAddr; + TUint32 iLen; + }; + +/// Gives a pointer resulting with aliging \a v with \a a. +/// @note \a a must be power of 2. +template T* Align( T* v, TUint a ) + { return (T*)( ((TUint8*)v) + ((-(TUint)v)&(a-1)) ); } + +/// Gives a pointer resulting with aliging \a v with \a a. +/// @note \a a must be power of 2. +template T Align( T v, TUint a ) + { return (v)+((-v)&(a-1)); } + +} + +#endif diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/virtio_io.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/virtio_io.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,42 @@ +/* +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Accenture Ltd +* +* Contributors: +* +* Description: This file is a part of sound driver for Syborg adaptation. +* +*/ + +#include "virtio_io.h" + +namespace VirtIo +{ + +void DIo::GetDeviceIds( TUint32 &aPeripheralId, TUint32 &aDeviceId ) + { + aPeripheralId = read( EIoID ); + aDeviceId = read( EIoDevType ); + } + +void DIo::SetQueueBase( TUint aQId, TAny* iDescRegion ) + { + TUint32 phAddr = iDescRegion?Epoc::LinearToPhysical( reinterpret_cast( iDescRegion ) ):0; + write(EIoQueueSelect, aQId); + write(EIoQueueBase, phAddr ); + SYBORG_VIRTIO_DEBUG("SetQueueBase Q%d %x", aQId, phAddr ); + } + + +TAny* DIo::GetQueueBase( TUint aQId) + { + write(EIoQueueSelect, aQId); + return reinterpret_cast( read(EIoQueueBase) ); + } + +} // namespace VirtIo diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/virtio_io.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/virtio_io.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,83 @@ +/* +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Accenture Ltd +* +* Contributors: +* +* Description: This file is a part of sound driver for Syborg adaptation. +* +*/ + +#ifndef VIRTIO_IO_H +#define VIRTIO_IO_H + +#include "virtio.h" +#include + +namespace VirtIo +{ + +class DIo : public DBase, public MIo + { +public: + DIo( TAny* aIoBase ): iIoBase( reinterpret_cast( aIoBase ) ) + { } + + virtual void GetDeviceIds( TUint32 &aPeripheralId, TUint32 &aDeviceId ); + + virtual void SetQueueBase( TUint aQId, TAny* iDescRegion ); + + virtual TAny* GetQueueBase( TUint aQId); + + virtual TUint GetQueueCount( TUint aQId ) + { + write(EIoQueueSelect, aQId); + return read(EIoQueueSize); + } + + virtual void PostQueue( TUint aQId ) + { write(EIoQueueNotify, aQId); SYBORG_VIRTIO_DEBUG("PostQueue Q%d", aQId ); } + + virtual TBool EnableInterrupt( TBool aEnable ) + { return swap(EIoInterruptEnable, aEnable?1:0); } + + virtual void SetStatus( TUint status ) + { write(EIoStatus, status ); } + + virtual void ClearInteruptStatus() + { write( EIoInterruptStatus, 1 ); } + + virtual TBool InteruptStatus() + { return read( EIoInterruptStatus ); } + + + void Reset() + { SetStatus( EStatusReset ); }; + + +private: + void write(TUint idx, TUint32 value ) + { iIoBase[idx] = value; } + + TUint32 read(TUint idx) + { return iIoBase[idx]; } + + TUint32 swap(TUint idx, TUint32 value ) + { + TUint32 t = iIoBase[idx]; + iIoBase[idx] = value; + return t; + } + + volatile TUint32* iIoBase; + + }; + +} // namespace VirtIo + +#endif diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/virtio_iohandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/virtio_iohandler.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,238 @@ +/* +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Accenture Ltd +* +* Contributors: +* +* Description: This file is a part of sound driver for Syborg adaptation. +* +*/ + +#include "virtio_iohandler.h" +#include "virtio_queue.h" +#include "virtio_io.h" + +namespace VirtIo +{ + +DIoHandler::DIoHandler( TAny* aVirtIoBase, TUint aIntNum, TDfcQue* aDfcQue ) + : iVirtIoBase( aVirtIoBase ), iIntNum( aIntNum ), iDfcQue( aDfcQue ), + iDfc( ServeDfc, this, 0 ), + iVirtIo( 0 ), iQueueCount( 3 ), iQueue( 0 ), + iClientCount( 0 ) + { + SYBORG_VIRTIO_DEBUG("DIoHandler IoBase %x DfcQ %x", iVirtIoBase, iDfcQue); + } + +TInt DIoHandler::Construct() + { + TInt err = KErrNone; + TUint i; + + SYBORG_VIRTIO_DEBUG("Creating DIo"); + + InstallIsr(); + + iVirtIo = new DIo(iVirtIoBase); + if (iVirtIo == NULL ) + { return KErrNoMemory; } + iVirtIo->SetStatus( EStatusAcknowledge + | EStatusDriverFound ); + + iQueue = new DQueue*[iQueueCount]; + + if (iQueue == NULL ) + { Wipe(); return KErrNoMemory; } + + // This is to make Wipe work + for ( i = 0; i < iQueueCount; ++i ) + { iQueue[i] = NULL; } + + for ( i = 0; i < iQueueCount; ++i ) + { + SYBORG_VIRTIO_DEBUG("Creating DQueue %d",i); + DQueue* q = new DQueue( + *iVirtIo, i, iVirtIo->GetQueueCount( i ) ); + if (!q) + { Wipe(); return KErrNoMemory; } + err = q->Construct(); + if (err != KErrNone) + { Wipe(); return err; } + iQueue[i] = q; + } + + iVirtIo->SetStatus( + EStatusAcknowledge + | EStatusDriverFound + | EStatusDriverInitialised ); + + iVirtIo->EnableInterrupt( ETrue ); + Interrupt::Enable(iIntNum); + return KErrNone; + } + +void DIoHandler::Wipe() + { + if (iQueue) + { + for ( TUint i = 0; i < iQueueCount; ++i ) + { + if (iQueue[i]) + { delete iQueue[i]; } + } + delete[] iQueue; + iQueue = NULL; + } + if (iVirtIo) + { + delete iVirtIo; + iVirtIo = NULL; + } + } + +DIoHandler::~DIoHandler() + { + + Interrupt::Disable(iIntNum); + UninstallIsr(); + iVirtIo->EnableInterrupt( EFalse ); + iDfc.Cancel(); + iVirtIo->ClearInteruptStatus(); + + WaitForCompletion(); + + iVirtIo->SetStatus( EStatusAcknowledge + | EStatusDriverFound ); + iVirtIo->SetStatus( EStatusAcknowledge ); + + Wipe(); + } + +MQueue& DIoHandler::Queue( TUint id ) + { return *(iQueue[id]); } + +void DIoHandler::ScheduleCallback() + { + iDfc.Enque(); + } + + +// Waits until device processes all pending requests +// This code should be really handled by each queue individually +void DIoHandler::WaitForCompletion() + { + SYBORG_VIRTIO_DEBUG("WaitForCompletion : {"); + + TInt st = Kern::PollingWait( &DIoHandler::CheckProcessing, this, 10, 100 ); + + ASSERT( st == KErrNone ); + + for ( TUint i = 0; i < iQueueCount; ++i ) + { + while ( iQueue[i]->Completed() ) + { InterruptHandler(); } + } + + SYBORG_VIRTIO_DEBUG("WaitForCompletion : }"); + } + +TBool DIoHandler::CheckProcessing( TAny* aSelf ) + { + DIoHandler* self = reinterpret_cast( aSelf ); + for ( TUint i = 0; i < self->iQueueCount; ++i ) + { + if (self->iQueue[i]->Processing()!=0) + { return EFalse; } + } + return ETrue; + } + +void DIoHandler::InstallIsr() + { + iDfc.SetDfcQ( iDfcQue ); + Interrupt::Bind(iIntNum,ServeIsr,this); + } + +void DIoHandler::UninstallIsr() + { + Interrupt::Unbind(iIntNum); + iDfc.Cancel(); + } + +void DIoHandler::ServeIsr( TAny* aSelf ) + { + DIoHandler* self = reinterpret_cast( aSelf ); + Interrupt::Clear( self->iIntNum ); + self->iVirtIo->ClearInteruptStatus(); + self->iDfc.Add(); + } + +void DIoHandler::ServeDfc( TAny* aSelf ) + { + reinterpret_cast( aSelf )->InterruptHandler(); + } + + +// Although the function notifies all clients +// usually only one of them is an adressee +// the rest would just check flags/compare numbers and return. +// If at least one client did some crucial processing +// (indicating that by returning EFalse from VirtIoCallback) +// then NotifyClients returns EFalse as well. +TBool DIoHandler::NotifyClients( MQueue& aQueue, Token aToken, TUint aBytesTransferred ) + { + TBool r = ETrue; + for ( TUint i = 0 ; i < iClientCount; ++i ) + { + r &= iClients[i]->VirtIoCallback( *this, aQueue, aToken, aBytesTransferred ); + } + return r; + } + +// Here buffers processed by the device are iterated. +// After the first serious buffer processing (as indicated by NotifyClients) +// further buffer processing is Deferred in another DFC callback. +void DIoHandler::InterruptHandler() + { + for ( TUint q = 0; q < iQueueCount; ++q ) + { + TUint transferred; + TUint cnt = ETrue; + do + { + Token t = Queue(q).GetBuf(transferred); + if (t) + { cnt = NotifyClients( Queue(q), t, transferred); } + else + { break; } + } while(cnt); + if (!cnt) + { + ScheduleCallback(); + break; + } + } + } + +void DIoHandler::UnregisterClient( MIoCallback* aClient ) + { + ASSERT( iClientCount ); + TUint i; + for ( i = 0; i < iClientCount; ++i) + { + if (iClients[i] == aClient ) + { break; } + } + ASSERT( i < iClientCount ); + --iClientCount; + // move the rest of the table one slot to the front + for ( ; i < iClientCount; ++i) + { iClients[i] = iClients[i+1]; } + } + +} // namespace VirtIo diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/virtio_iohandler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/virtio_iohandler.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,93 @@ +/* +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Accenture Ltd +* +* Contributors: +* +* Description: This file is a part of sound driver for Syborg adaptation. +* +*/ + +#ifndef VIRTIO_IOHANDLER_H +#define VIRTIO_IOHANDLER_H + +#include "virtio.h" +#include + +namespace VirtIo +{ + +class DQueue; + +class DIo; + + +class DIoHandler : public DBase, public MIoHandler + { + static const TUint KMaxClients = 4; +public: + DIoHandler( TAny* aVirtIoBase, TUint aIntNum, TDfcQue* aDfcQue ); + + virtual void RegisterClient( MIoCallback* aClient ) + { + ASSERT( iClientCount < KMaxClients ); + iClients[iClientCount++] = aClient; + } + + virtual void UnregisterClient( MIoCallback* aClient ); + + TInt Construct(); + + + virtual ~DIoHandler(); + + virtual MQueue& Queue( TUint id ); + +private: + void ScheduleCallback(); + + void WaitForCompletion(); + + void Wipe(); + + static TBool CheckProcessing( TAny* aSelf ); + + void InstallIsr(); + + void UninstallIsr(); + + static void ServeIsr( TAny* aSelf ); + + static void ServeDfc( TAny* aSelf ); + + TBool NotifyClients( MQueue& aQueue, Token aToken, TUint aBytesTransferred ); + + void InterruptHandler(); + + TAny* iVirtIoBase; + TUint iIntNum; + + TDfcQue* iDfcQue; + TDfc iDfc; + + //managed + DIo* iVirtIo; + + TUint iQueueCount; + //double managed + DQueue** iQueue; + + TUint iClientCount; + MIoCallback* iClients[KMaxClients]; + + }; + + +} // namespace VirtIo + +#endif diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/virtio_queue.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/virtio_queue.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,328 @@ +/* +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Accenture Ltd +* +* Contributors: +* +* Description: This file is a part of sound driver for Syborg adaptation. +* +*/ + +#include "virtio_queue.h" + +#define ENABLE_QEMU_AUDIO_MODEL_BUG_WORKAROUND +#define ENABLE_QEMU_VIRTIO_CLEANUP_BUG_WORKAROUND +#define PHYS_ADDR(x) Epoc::LinearToPhysical( reinterpret_cast(x)) + +namespace VirtIo +{ + + +DQueue::DQueue( MIo& aVirtIo, TUint aId, TUint aCount ) + : iVirtIo( aVirtIo ), iId( aId ), iCount( aCount ) + { + } + +TInt DQueue::Construct() + { + TInt r = AllocQueue(); + if (r!=KErrNone) + { return r; } + PreInitQueue(); + iVirtIo.SetQueueBase( iId, iDesc ); + PostInitQueue(); + return KErrNone; + } + +void DQueue::Wipe() + { + if ( iChunk ) + { + iChunk->Close( NULL ); + iChunk = NULL; + } +#ifndef ENABLE_QEMU_VIRTIO_CLEANUP_BUG_WORKAROUND + if ( iPhysAddr ) + { Epoc::FreePhysicalRam( iPhysAddr ); } +#endif + iPhysAddr = 0; + } + +DQueue::~DQueue() + { + Wipe(); + } + +// +// Implementation here is that descs are allocated from the one starting with lowest index, +TInt DQueue::AddBuf( const TAddrLen aScatterList[], TUint32 aOutNum, TUint32 aInNum, Token aToken) + { + SYBORG_VIRTIO_DEBUG("AddBuf Q%x %x l%x %x,%x %x", + iId, aScatterList[0].iAddr, aScatterList[0].iLen, aOutNum, aInNum, aToken ); + TUint outLeft = aOutNum; + TUint inLeft = aInNum; + TInt first = -1; + TInt last = -1; + TUint totalLen = 0; + // @TODO maintain freedescs counter to know if the below is going to success from the outset. + // alloc and initialise descs + for ( TUint i = 0, j = 0; (i < iCount) && (outLeft+inLeft); ++i ) + { + if (iDesc[i].iFlags == KFreeDescriptorMarker) + { + if (first<0) + { first = i; } + iDesc[i].iFlags = ((outLeft)? 0 : TRingDesc::EFlagWrite); + iDesc[i].iNext = KFreeDescriptorMarker; + iDesc[i].iAddr = aScatterList[j].iAddr; + iDesc[i].iLen = aScatterList[j].iLen; + totalLen += aScatterList[j].iLen; + iToken[i].iToken = aToken; + iToken[i].iTotalLen = 0; + if ( last >=0 ) + { + iDesc[last].iNext = i; + iDesc[last].iFlags |= TRingDesc::EFlagNext; + } + last = i; + if (outLeft) + { --outLeft; } + else + { --inLeft; } + j++; + } + } + if (outLeft+inLeft) // rollback descs if not all could have been claimed + { + if (first>=0) + { FreeDescs(first); } + return KErrNotReady; + } + iToken[first].iTotalLen = totalLen; + + // fill a slot in avail ring + iAvail->iRing[Slot(iAvail->iIdx)] = first; + ++iAvail->iIdx; + + return KErrNone; + } + +// bases on the assumption that the lowest desc index with given aToken value is used (see addBuf) +// @todo make sure the buffer is not yet posted +TInt DQueue::DetachBuf( Token aToken ) + { + TUint myDescId = KFreeDescriptorMarker; + for ( TIdx i = iNextAvailToSync; i != iAvail->iIdx ; ++i ) + { + TUint availSlot = Slot( i ); + TUint descId = iAvail->iRing[availSlot]; + if ( descId < iCount ) + { + if (iToken[descId].iToken == aToken) + { + myDescId = descId; + break; + } + } + } + if ( myDescId != KFreeDescriptorMarker ) + { return KErrNotFound; } + FreeDescs( myDescId ); + return KErrNone; + } + +Token DQueue::GetBuf( TUint& aLen ) + { + TIdx usedIdx = iUsed->iIdx; + ASSERT( ((TIdx)iNextUsedToRead) <= usedIdx ); + if (usedIdx == ((TIdx)iNextUsedToRead)) + { return 0; } + TUint nextUsedSlot = Slot(iNextUsedToRead); + TUint len = iUsed->iRing[nextUsedSlot].iLen; + TUint descId = iUsed->iRing[nextUsedSlot].iId; + ASSERT(descIdiIdx - iFirstEverToSync)) + - ((TIdx)(iUsed->iIdx - iFirstEverToRead)); } + +TInt DQueue::Completed() + { return ((TIdx)(iUsed->iIdx - iNextUsedToRead)); } + +void DQueue::Sync() + { + SYBORG_VIRTIO_DEBUG("Sync Q%d, %x..%x", + iId, iNextAvailToSync, iAvail->iIdx ); + if ( ((TIdx)iNextAvailToSync) == iAvail->iIdx) + { return; } + DumpAvailPending(); + + iNextAvailToSync = iAvail->iIdx; + iVirtIo.PostQueue( iId ); + } + +void DQueue::DumpUsedPending() + { + for (TIdx i = iNextUsedToRead; i != iUsed->iIdx; ++i ) + { DumpUsed( Slot(i) ); } + } + +void DQueue::DumpUsed(TUint usedSlot) + { + SYBORG_VIRTIO_DEBUG("Usedslot = %x, aLen = %x, descId=%x", usedSlot, (TUint32) iUsed->iRing[usedSlot].iLen, iUsed->iRing[usedSlot].iId); + TUint descId = iUsed->iRing[usedSlot].iId; + DumpDescs( descId ); + } + +void DQueue::DumpAvailPending() + { + for (TIdx i = iNextAvailToSync; i != iAvail->iIdx; ++i ) + { DumpAvail( Slot(i) ); } + } + +void DQueue::DumpAvail(TUint availSlot) + { + SYBORG_VIRTIO_DEBUG("Q%d, availslot = %x", iId, availSlot); + TUint descId = iAvail->iRing[availSlot]; + DumpDescs( descId ); + } + +void DQueue::DumpDescs(TUint descId ) + { + do { + TRingDesc& d = iDesc[descId]; + SYBORG_VIRTIO_DEBUG(" Desc %x,addr %x, len %x, flags %x, next %x", + (TUint32)descId, (TUint32)d.iAddr, (TUint32)d.iLen, (TUint32)d.iFlags, (TUint32)d.iNext ); + if ((d.iFlags&TRingDesc::EFlagNext)==0) + { break; } + descId = d.iNext; + } while (ETrue); + } + +void DQueue::DumpAll() + { + DumpAvailPending(); + DumpUsedPending(); + } + +void DQueue::FreeDescs( TUint firstDescIdx ) + { + TInt i = firstDescIdx; + Token token = iToken[firstDescIdx].iToken; + while (i>=0) + { + ASSERT( ( ((TUint)i) < iCount ) ); + TUint flags = iDesc[i].iFlags; + ASSERT( flags != KFreeDescriptorMarker ); + iDesc[i].iFlags = KFreeDescriptorMarker; + ASSERT( iToken[i].iToken == token ); + iToken[i].iToken = 0; + iToken[i].iTotalLen = 0; + i = (flags&TRingDesc::EFlagNext) + ? iDesc[i].iNext : -1; + } + } + +TUint8* DQueue::AllocMem( TUint aSize ) + { + TInt r = KErrNone; + +#ifdef ENABLE_QEMU_VIRTIO_CLEANUP_BUG_WORKAROUND + // note this is second part of workaround that deals + // with the issue that memory once assigned to queuebase cannot be + // changed, + // if queuebase != 0 this is because it was set when the driver + // was loaded previous time + + iPhysAddr = (TUint32) iVirtIo.GetQueueBase( iId ); + iPhysMemReallyAllocated = (iPhysAddr == 0); + if (iPhysMemReallyAllocated) + { r = Epoc::AllocPhysicalRam(aSize, iPhysAddr, 0 ); } + +#endif + + if (r!=KErrNone ) + { return NULL; } + + r = DPlatChunkHw::New( iChunk, iPhysAddr, aSize, + EMapAttrSupRw | EMapAttrL2Uncached | EMapAttrL1Uncached ); + + if (r!=KErrNone ) + { + if ( iPhysMemReallyAllocated ) + { Epoc::FreePhysicalRam( iPhysAddr, aSize ); } + iChunk->Close( NULL ); + return NULL; + } + + ASSERT( r == KErrNone ); + return reinterpret_cast( iChunk->LinearAddress() ); + } + +TInt DQueue::AllocQueue() + { + iDescSize = iCount * sizeof(TRingDesc); + iAvailSize = sizeof(TRingAvail) + (iCount-1) * sizeof(((TRingAvail*)0)->iRing[0]); + iTokenSize = iCount * sizeof(TTransactionInfo); + TUint usedOffset = Align( iDescSize + iAvailSize, KVirtIoAlignment ); + TUint iUsedSize = sizeof(TRingUsed) + (iCount-1) * sizeof(((TRingUsed*)0)->iRing[0]); + TUint size = usedOffset + iUsedSize; + TUint8* iMemAligned; + + iMemAligned = AllocMem( size ); + + if (!iMemAligned) + { return KErrNoMemory; } + + iDesc = reinterpret_cast( iMemAligned ); + iAvail = reinterpret_cast( iMemAligned + iDescSize ); + iUsed = reinterpret_cast( iMemAligned + usedOffset ); + iToken = reinterpret_cast( Kern::Alloc( iTokenSize ) ); + SYBORG_VIRTIO_DEBUG("DQueue %d, Virt iDesc=%x,iAvail=%x,iToken=%x,iUsed=%x", + iId, iDesc, iAvail, iToken, iUsed ); + SYBORG_VIRTIO_DEBUG("DQueue %d, Phys iDesc=%x, iUsed=%x", + iId, PHYS_ADDR(iDesc), PHYS_ADDR(iUsed) ); + ASSERT( ((PHYS_ADDR(iUsed)-PHYS_ADDR(iDesc))) == ((TUint32)((TUint8*)iUsed-(TUint8*)iDesc)) ); + return KErrNone; + } + +void DQueue::PreInitQueue() + { + memset(iDesc, -1, iDescSize ); + memset( ((TUint8*) iAvail) + 4, -1, iDescSize - 4 ); + memset( ((TUint8*) iUsed) + 4, -1, iDescSize - 4 ); + + iAvail->iFlags = 0; // no notifications from control queue + iUsed->iFlags = 0; + if ( iPhysMemReallyAllocated ) + { + iAvail->iIdx = 0; + iUsed->iIdx = 0; + } + } + +void DQueue::PostInitQueue() + { + iFirstEverToSync = iNextAvailToSync = iAvail->iIdx; + iFirstEverToRead = iNextUsedToRead = iUsed->iIdx; + } + + +} // namespace VirtIo diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/soundsc/virtio_queue.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/soundsc/virtio_queue.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,139 @@ +/* +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Accenture Ltd +* +* Contributors: +* +* Description: This file is a part of sound driver for Syborg adaptation. +* +*/ + +#ifndef VIRTIO_QUEUE_H +#define VIRTIO_QUEUE_H + +#include "virtio.h" +#include + +namespace VirtIo +{ + +/// @brief implements VirtIo Queue. +/// +/// +/// @note functions are not enclosed with any synchronisation primitives. +/// However, implementation is believed to split operations in 3 groups with the following concurrency constraints: +///
  • A GetBuf, DetachBuf +///
  • B AddBuf +///
  • C Processing, Completed, Sync +/// Group C can be executed concurrently with any other functions. +/// Group A can be executed concurrently with a group B function. +/// Group A or B function cannot be executed concurrently with function from the same group. +/// +/// Memory barries would have to be introduced for SMP. +/// +class DQueue : public DBase, public MQueue + { + typedef TUint16 TIdx; + + struct TTransactionInfo + { + Token iToken; + TUint iTotalLen; + }; + + static const TUint KFreeDescriptorMarker = 0xFFFF; + +public: + + /// @brief Creates a VirtIo Queue with a MIo object, Queue Id, + /// and descriptor count/ring lenght. + DQueue( MIo& aVirtIo, TUint aId, TUint aCount ); + + /// Allocates resources + TInt Construct(); + + virtual ~DQueue(); + +public: // implementation of MQueue + + virtual TInt AddBuf( const TAddrLen aScatterList[], TUint32 aOutNum, TUint32 aInNum, Token aToken); + + virtual TInt DetachBuf( Token aToken ); + + virtual Token GetBuf( TUint& aLen ); + + virtual void Sync(); + + virtual TUint Id() + { return iId; } + + virtual TBool Restart() + { return ETrue; } + + virtual TInt Processing(); + + virtual TInt Completed(); + +public: // Debug functions + void DumpUsedPending(); + + void DumpUsed(TUint usedSlot); + void DumpAvailPending(); + + void DumpAvail(TUint availSlot); + void DumpDescs(TUint descId ); + + virtual void DumpAll(); + +private: + void Wipe(); + + TUint Slot( TUint i ) + { return i & (iCount - 1); } + + void FreeDescs( TUint firstDescIdx ); + + TUint8* AllocMem( TUint aSize ); + + TInt AllocQueue(); + + void PreInitQueue(); + + void PostInitQueue(); + +private: + MIo& iVirtIo; + const TUint iId; + const TUint iCount; + volatile TUint iNextUsedToRead; + TUint iFirstEverToRead; + volatile TUint iNextAvailToSync; + TUint iFirstEverToSync; + + TUint iDescSize; + TUint iAvailSize; + TUint iTokenSize; + TUint iUsedSize; + + TRingDesc* iDesc; + TRingAvail* iAvail; + volatile TRingUsed* iUsed; + TTransactionInfo* iToken; + + // managed + TUint8* iMem; + TPhysAddr iPhysAddr; + TBool iPhysMemReallyAllocated; + DPlatChunkHw* iChunk; + + }; + + +} // namespace VirtIo + +#endif diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/specific/syborg.cpp --- a/baseport/syborg/specific/syborg.cpp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/specific/syborg.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -27,7 +27,7 @@ void TSyborg::Init3() { -// SetTimerMode(KHwBaseCounterTimer, ETimerModePeriodic); +// SetTimerMode(KHwBaseCounterTimer, ETimerModePeriodic); // EnableTimer(KHwBaseCounterTimer, EEnable); } @@ -105,10 +105,12 @@ EXPORT_C TInt TSyborg::VideoRamSize() { - return 4*640*480; + + return 4*854*854; // Now allow for 854 x 854 display, instead of 480 x 640 + } -// !@! +// !@! EXPORT_C TPhysAddr TSyborg::VideoRamPhys() { #if 0 diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/specific/syborg.h --- a/baseport/syborg/specific/syborg.h Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/specific/syborg.h Tue Apr 06 17:00:22 2010 +0100 @@ -52,8 +52,8 @@ const TUint KHwSVPNetDevice = KHwBasePeripherals + 0x0c*KHwLinSeparation; const TUint KHwSVPNandDevice = KHwBasePeripherals + 0x0d*KHwLinSeparation; const TUint KHwSVPAudioDevice = KHwBasePeripherals + 0x0e*KHwLinSeparation; -const TUint KHwSVPPlatformDevice = KHwBasePeripherals + 0x0f*KHwLinSeparation; - +const TUint KHwSVPWebcameraDevice = KHwBasePeripherals + 0x0f*KHwLinSeparation; +const TUint KHwSVPPlatformDevice = KHwBasePeripherals + 0x10*KHwLinSeparation; enum TSyborgInterruptId { @@ -66,7 +66,9 @@ EIntSerial0 = 5, EIntSerial1 = 6, EIntSerial2 = 7, - EIntSerial3 = 8 + EIntSerial3 = 8, + EIntNet0 = 9, + EIntAudio0 = 10 }; // Timer Mode diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/svpframebuffer/svpframebuffer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/svpframebuffer/svpframebuffer.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1059 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Accenture Ltd - Syborg framebuffer improvements, now auto determines frame size from board model, performance and memory improvements +* +* Description: Minimalistic frame buffer driver +* +*/ +#include +#include "platform.h" +#include +#include +#include +#include + +#include +#include "svpframebuffer.h" + +DLcdPowerHandler * DLcdPowerHandler::pLcd = NULL; + +TPhysAddr Syborg::VideoRamPhys; +TPhysAddr Syborg::VideoRamPhysSecure; // Secure display memory + +TPhysAddr TSyborg::VideoRamPhys() +{ + __KTRACE_OPT(KEXTENSION,Kern::Printf("TSyborg::VideoRamPhys: VideoRamPhys=0x%x", Syborg::VideoRamPhys)); + return Syborg::VideoRamPhys; +} + +TPhysAddr TSyborg::VideoRamPhysSecure() +{ + return Syborg::VideoRamPhysSecure; +} + +LOCAL_C TInt DoHalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2) +{ + DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr; + return pH->HalFunction(aFunction,a1,a2); +} + +static void rxMsg(TAny* aPtr) +{ + DLcdPowerHandler& h=*(DLcdPowerHandler*)aPtr; + TMessageBase* pM = h.iMsgQ.iMessage; + if(pM) + h.HandleMsg(pM); +} + +static void power_up_dfc(TAny* aPtr) +{ + ((DLcdPowerHandler*)aPtr)->PowerUpDfc(); +} + +void power_down_dfc(TAny* aPtr) +{ + ((DLcdPowerHandler*)aPtr)->PowerDownDfc(); +} + +void DLcdPowerHandler::DisplayOn() +{ + PowerUpLcd(iSecureDisplay); + iDisplayOn = ETrue; +} + +void DLcdPowerHandler::DisplayOff() +{ + PowerDownLcd(); + iDisplayOn = EFalse; +} + +void DLcdPowerHandler::SwitchDisplay(TBool aSecure) + { + if(aSecure) + { + if(!iSecureDisplay) + { + DisplayOff(); + iSecureDisplay = ETrue; + DisplayOn(); + } + } + else + { + if(iSecureDisplay) + { + DisplayOff(); + iSecureDisplay = EFalse; + DisplayOn(); + } + } + } + +void DLcdPowerHandler::PowerUpDfc() +{ + DisplayOn(); + PowerUpDone(); +} + +void DLcdPowerHandler::PowerDownDfc() +{ + DisplayOff(); + + PowerDownDone(); +} + +void DLcdPowerHandler::PowerDown(TPowerState) +{ + iPowerDownDfc.Enque(); +} + +void DLcdPowerHandler::PowerUp() +{ + iPowerUpDfc.Enque(); +} + +void DLcdPowerHandler::PowerUpLcd(TBool aSecure) +{ + + WriteReg(iPortAddr, FB_ENABLED, 0); + WriteReg(iPortAddr, FB_BASE, aSecure ? iSecurevRamPhys : ivRamPhys); + + WriteReg(iPortAddr, FB_BLANK, 0); + WriteReg(iPortAddr, FB_BPP, 32); + WriteReg(iPortAddr, FB_COLOR_ORDER, 0); + WriteReg(iPortAddr, FB_BYTE_ORDER, 0); + WriteReg(iPortAddr, FB_PIXEL_ORDER, 0); + WriteReg(iPortAddr, FB_INT_MASK, 0); + WriteReg(iPortAddr, FB_ENABLED, 1); + +// We don't write the Height and Width of the framebuffer, this is controlled by the board model + +} + +void DLcdPowerHandler::PowerDownLcd() +{ + WriteReg(iPortAddr, FB_BLANK, 1); +} + +DLcdPowerHandler::DLcdPowerHandler() + : DPowerHandler(KLitLcd), + iMsgQ(rxMsg,this,NULL,1), + iPowerUpDfc(&power_up_dfc,this,6), + iPowerDownDfc(&power_down_dfc,this,7) +{ +} + +void DLcdPowerHandler::ScreenInfo(TScreenInfoV01& anInfo) +{ + anInfo.iWindowHandleValid = EFalse; + anInfo.iWindowHandle = NULL; + anInfo.iScreenAddressValid = ETrue; + anInfo.iScreenAddress = (TAny *)(iChunk->LinearAddress()); + anInfo.iScreenSize.iWidth = iVideoInfo.iSizeInPixels.iWidth; + anInfo.iScreenSize.iHeight = iVideoInfo.iSizeInPixels.iHeight; +} + +void DLcdPowerHandler::HandleMsg(TMessageBase* aMsg) +{ + if(aMsg->iValue) + DisplayOn(); + else + DisplayOff(); + aMsg->Complete(KErrNone,ETrue); +} + +void DLcdPowerHandler::WsSwitchOnScreen() +{ + TThreadMessage& m = Kern::Message(); + m.iValue = ETrue; + m.SendReceive(&iMsgQ); +} + +void DLcdPowerHandler::WsSwitchOffScreen() +{ + TThreadMessage& m = Kern::Message(); + m.iValue = EFalse; + m.SendReceive(&iMsgQ); +} + +TInt DLcdPowerHandler::GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure) +{ + NKern::FMWait(&iLock); + if(aSecure) + aInfo = iSecureVideoInfo; + else + aInfo = iVideoInfo; + NKern::FMSignal(&iLock); + return KErrNone; +} + +TInt DLcdPowerHandler::GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo) +{ + if(aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes) + return KErrArgument; + + NKern::FMWait(&iLock); + aInfo = iVideoInfo; + NKern::FMSignal(&iLock); + + if(aMode != aInfo.iDisplayMode) + { + aInfo.iOffsetToFirstPixel = KCOnfigOffsetToFirstPixel; + aInfo.iIsPalettized = KConfigIsPalettized; + aInfo.iOffsetBetweenLines = iVideoInfo.iSizeInPixels.iWidth*4; //Offset depends on width of framebuffer + aInfo.iBitsPerPixel = KConfigBitsPerPixel; + } + return KErrNone; +} + +TInt DLcdPowerHandler::AllocateFrameBuffer() +{ + // Allocate physical RAM for video + + //read width and height of display from board model and allocate size + TInt width = ReadReg(iPortAddr, FB_WIDTH); + TInt height = ReadReg(iPortAddr, FB_HEIGHT); + + iSize = 4*width*height; //*4 as 32bits per pixel + + NKern::ThreadEnterCS(); + TInt r = Epoc::AllocPhysicalRam(iSize,Syborg::VideoRamPhys); + if (r != KErrNone) + { + NKern::ThreadLeaveCS(); + Kern::Fault("AllocVideoRam",r); + } + + // Map the video RAM + ivRamPhys = TSyborg::VideoRamPhys(); + + r = DPlatChunkHw::New(iChunk,ivRamPhys,iSize,EMapAttrUserRw|EMapAttrBufferedC); + + NKern::ThreadLeaveCS(); + + if(r != KErrNone) + return r; + + TUint* pV = (TUint*)iChunk->LinearAddress(); + + // Allocate physical RAM for secure display + NKern::ThreadEnterCS(); + r = Epoc::AllocPhysicalRam(iSize,Syborg::VideoRamPhysSecure); + if (r != KErrNone) + { + NKern::ThreadLeaveCS(); + Kern::Fault("AllocVideoRam 2",r); + } + iSecurevRamPhys = ivRamPhys + iSize; + TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,iSize,EMapAttrUserRw|EMapAttrBufferedC); + + NKern::ThreadLeaveCS(); + + if(r2 != KErrNone) + return r2; + + TUint* pV2 = (TUint*)iSecureChunk->LinearAddress(); + + //width and height set by reading board model + iVideoInfo.iSizeInPixels.iWidth = width; + iVideoInfo.iSizeInPixels.iHeight = height; + + //offset between lines depends on width of screen + iVideoInfo.iOffsetBetweenLines = width*4; + + iVideoInfo.iDisplayMode = KConfigLcdDisplayMode; + iVideoInfo.iOffsetToFirstPixel = KConfigOffsetToFirstPixel; + + iVideoInfo.iIsPalettized = KConfigIsPalettized; + iVideoInfo.iBitsPerPixel = KConfigBitsPerPixel; + iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips; + iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips; + iVideoInfo.iIsMono = KConfigIsMono; + iVideoInfo.iVideoAddress = (TInt)pV; + iVideoInfo.iIsPixelOrderLandscape = KConfigPixelOrderLandscape; + iVideoInfo.iIsPixelOrderRGB = KConfigPixelOrderRGB; + + iSecureVideoInfo = iVideoInfo; + iSecureVideoInfo.iVideoAddress = (TInt)pV2; + + // Alloc Physical RAM for the Composition Buffers used by OpenWF + // double and round the page size + TUint round = 2*Kern::RoundToPageSize(iSize); + + r=Epoc::AllocPhysicalRam(round , iCompositionPhysical); + if(r!=KErrNone) + { + return r; + } + + return KErrNone; +} + + +TInt DLcdPowerHandler::SetDisplayMode(TInt aMode) +{ + if(aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes) + return KErrArgument; + + // store the current mode + iVideoInfo.iDisplayMode = aMode; + + // store the current mode for secure screen + iSecureVideoInfo.iDisplayMode = aMode; + + return KErrNone; +} + +TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2) +{ + TInt r=KErrNone; + switch(aFunction) + { + case EDisplayHalScreenInfo: + { + TPckgBuf vPckg; + ScreenInfo(vPckg()); + Kern::InfoCopy(*(TDes8*)a1,vPckg); + break; + } + case EDisplayHalWsRegisterSwitchOnScreenHandling: + { + iWsSwitchOnScreen=(TBool)a1; + break; + } + case EDisplayHalWsSwitchOnScreen: + { + WsSwitchOnScreen(); + break; + } + case EDisplayHalModeCount: + { + TInt ndm = KConfigLcdNumberOfDisplayModes; + kumemput32(a1, &ndm, sizeof(ndm)); + break; + } + case EDisplayHalSetMode: + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("EDisplayHalSetMode")); + __SECURE_KERNEL( + if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetMode"))) + return KErrPermissionDenied; + ) + r = SetDisplayMode((TInt)a1); + break; + } + case EDisplayHalMode: + { + kumemput32(a1, &iVideoInfo.iDisplayMode, sizeof(iVideoInfo.iDisplayMode)); + r = KErrNone; + break; + } + case EDisplayHalSetPaletteEntry: + { + __SECURE_KERNEL( + if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetPaletteEntry"))) + return KErrPermissionDenied; + ) + r = KErrNotSupported; + break; + } + case EDisplayHalPaletteEntry: + { + TInt entry; + kumemget32(&entry, a1, sizeof(TInt)); + r = KErrNotSupported; + break; + } + case EDisplayHalSetState: + { + __SECURE_KERNEL( + if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetState"))) + return KErrPermissionDenied; + ) + if((TBool)a1) + WsSwitchOnScreen(); + else + WsSwitchOffScreen(); + break; + } + case EDisplayHalState: + { + kumemput32(a1, &iDisplayOn, sizeof(TBool)); + break; + } + case EDisplayHalColors: + { + TInt mdc = 1<<24; + kumemput32(a1, &mdc, sizeof(mdc)); + break; + } + case EDisplayHalCurrentModeInfo: + { + TPckgBuf vPckg; + r = GetCurrentDisplayModeInfo(vPckg(), (TBool)a2); + if(KErrNone == r) + Kern::InfoCopy(*(TDes8*)a1,vPckg); + break; + } + case EDisplayHalSpecifiedModeInfo: + { + TPckgBuf vPckg; + TInt mode; + kumemget32(&mode, a1, sizeof(mode)); + r = GetSpecifiedDisplayModeInfo(mode, vPckg()); + if(KErrNone == r) + Kern::InfoCopy(*(TDes8*)a2,vPckg); + break; + } + case EDisplayHalSecure: + { + kumemput32(a1, &iSecureDisplay, sizeof(TBool)); + break; + } + case EDisplayHalSetSecure: + { + __SECURE_KERNEL( + if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetSecure"))) + return KErrPermissionDenied; + ) + SwitchDisplay((TBool)a1); + break; + } + default: + { + r = KErrNotSupported; + break; + } + } + return r; +} + +TInt DLcdPowerHandler::Create() +{ + __KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::Create") ); + pLcd = this; + + iPortAddr = KHwBaseClcd; + + TInt r = AllocateFrameBuffer(); + if(r == KErrNone) + { + r = Kern::AddHalEntry(EHalGroupDisplay,DoHalFunction,this); + } + + if(r != KErrNone) + { + __KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::Create failed %d", r) ); + return r; + } + + iPowerUpDfc.SetDfcQ(iDfcQ); + iPowerDownDfc.SetDfcQ(iDfcQ); + iMsgQ.SetDfcQ(iDfcQ); + iMsgQ.Receive(); + + Add(); + DisplayOn(); + + return KErrNone; +} + +/** + * Register the call back function. + * Components interested in receiving notification of the Vsync interrupt should register a callback function. + */ +EXPORT_C TInt DLcdPowerHandler::RegisterCallback(TLcdUserCallBack* aCbPtr) +{ + __KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::RegisterCallBack %08x\n",aCbPtr->iCbFn) ); + + TInt irq=__SPIN_LOCK_IRQSAVE(callbackLock); + + if(aCbPtr != NULL) + { + if ( pLcd->iAppCallBk[0] == NULL ) + { + pLcd->iAppCallBk[0] = aCbPtr; + } + else + { + if((pLcd->iAppCallBk[1] == NULL) && (pLcd->iAppCallBk[0]->iCbFn != aCbPtr->iCbFn)) + { + pLcd->iAppCallBk[1] = aCbPtr; + } + else + { + __SPIN_UNLOCK_IRQRESTORE(callbackLock,irq); + return KErrInUse; + } + } + + __SPIN_UNLOCK_IRQRESTORE(callbackLock,irq); + __KTRACE_OPT(KEXTENSION ,Kern::Printf("iCbFn) ); + return KErrNone; + } + else + { + __SPIN_UNLOCK_IRQRESTORE(callbackLock,irq); + __KTRACE_OPT(KEXTENSION, Kern::Printf("Error: The supplied listener's callback is NULL")); + return KErrArgument; + } +} + + +/** + *DeRegister the call back function + */ +EXPORT_C void DLcdPowerHandler::DeRegisterCallback(TLcdUserCallBack* aCbPtr) +{ + __KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::DeRegisterCallBack %08x\n ",aCbPtr->iCbFn) ); + + TInt irq=__SPIN_LOCK_IRQSAVE(callbackLock); + if(aCbPtr != NULL) + { + if( pLcd->iAppCallBk[0] != NULL) + { + if ( (pLcd->iAppCallBk[0]->iDataPtr == aCbPtr->iDataPtr) && (pLcd->iAppCallBk[0]->iCbFn == aCbPtr->iCbFn) ) + { + pLcd->iAppCallBk[0] = NULL; + } + } + + if( pLcd->iAppCallBk[1] != NULL) + { + if ( (pLcd->iAppCallBk[1]->iDataPtr == aCbPtr->iDataPtr) && (pLcd->iAppCallBk[1]->iCbFn == aCbPtr->iCbFn) ) + { + pLcd->iAppCallBk[1] = NULL; + } + } + } + __SPIN_UNLOCK_IRQRESTORE(callbackLock,irq); + __KTRACE_OPT(KEXTENSION ,Kern::Printf("iCbFn) ); +} + +/** + Constructor +*/ +DDisplayPddSyborg::DDisplayPddSyborg(): + iPendingBuffer(NULL), + iActiveBuffer(NULL), + iChunk(NULL), + iLcdCallback(NULL), + iVSyncDfc(&VSyncDfcFn, this, KVSyncDfcPriority) + { + __GCE_DEBUG_PRINT("DDisplayPddSyborg::DDisplayPddSyborg\n"); + + iPostFlag = EFalse; + } + +/** + Destructor +*/ +DDisplayPddSyborg::~DDisplayPddSyborg() + { + __GCE_DEBUG_PRINT("DDisplayPddSyborg::~DDisplayPddSyborg() \n"); + + if(iLcdCallback) + { + DLcdPowerHandler::pLcd->DeRegisterCallback(iLcdCallback) ; + delete iLcdCallback; + iLcdCallback = NULL; + } + + //The DFC Queue is owned by DLcdPowerHandler so we shouldn't call Destroy() at this point. + if (iDfcQ) + { + iDfcQ=NULL; + } + + DChunk* chunk = (DChunk*) __e32_atomic_swp_ord_ptr(&iChunk, 0); + + if(chunk) + { + Kern::ChunkClose(chunk); + } + + } + +/** + Set the Legacy Mode by setting the appropriate Frame control value. + +*/ +TInt DDisplayPddSyborg::SetLegacyMode() + { + __GCE_DEBUG_PRINT("DDisplayPddSyborg::SetLegacyMode()\n"); + + return KErrNone; + } + +/** + Set the GCE mode by posting a composition buffer. + +*/ +TInt DDisplayPddSyborg::SetGceMode() + { + __GCE_DEBUG_PRINT("DDisplayPddSyborg::SetGceMode()\n"); + + PostCompositionBuffer(&iLdd->iCompositionBuffer[0]); + return KErrNone; + } + +/** + @param aDegOfRot The requested rotation + @return KErrNone +*/ +TInt DDisplayPddSyborg::SetRotation(RDisplayChannel::TDisplayRotation aDegOfRot) + { + return KErrNone; + } + +/** + Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization + with V Sync so it will take affect in the next V Sync after that) and also set the buffer provided as the buffer to + be posted next. Layer 3 is associated with user buffers. + + @param aNode Pointer to the User buffer to post. +*/ +TInt DDisplayPddSyborg::PostUserBuffer(TBufferNode* aNode) + { + + __GCE_DEBUG_PRINT2("DDisplayPddSyborg::PostUserBuffer : aNode->iAddress = %08x\n", aNode->iAddress); + + if(iPendingBuffer) + { + iPendingBuffer->iState = EBufferFree; + if (!(iPendingBuffer->iType == EBufferTypeUser) ) + { + iPendingBuffer->iFree = ETrue; + } + } + + aNode->iState = EBufferPending; + iPendingBuffer = aNode; + iPostFlag = ETrue; + + // Activate the posted buffer + TUint32 physicalAddress = Epoc::LinearToPhysical( aNode->iAddress ); + WriteReg(DLcdPowerHandler::pLcd->iPortAddr, DLcdPowerHandler::FB_BASE, physicalAddress ); + /* Queue a DFC to complete the request*/ + iVSyncDfc.Enque(); + + return KErrNone; + } + +/** + Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization + with V Sync so it will take affect in the next V Sync after that) and also set the buffer provided as the buffer to + be posted next. Layer 1 and 2 are associated with composition buffers 0 and 1 respectively. + + @param aNode Pointer to the Composition buffer to post. +*/ +TInt DDisplayPddSyborg::PostCompositionBuffer(TBufferNode* aNode) + { + + __GCE_DEBUG_PRINT2("DDisplayPddSyborg::PostCompositionBuffer : aNode->iAddress = %08x\n", aNode->iAddress); + + if(iPendingBuffer) + { + iPendingBuffer->iState = EBufferFree; + if (iPendingBuffer->iType == EBufferTypeUser) + { + RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrCancel); + } + else + { + iPendingBuffer->iFree = ETrue; + } + } + aNode->iState = EBufferPending; + aNode->iFree = EFalse; + iPendingBuffer = aNode; + iPostFlag = ETrue; + + // Activate the posted buffer + TUint32 physicalAddress = Epoc::LinearToPhysical( aNode->iAddress ); + WriteReg(DLcdPowerHandler::pLcd->iPortAddr, DLcdPowerHandler::FB_BASE, physicalAddress ); + + /* Queue a DFC to complete the request*/ + iVSyncDfc.Enque(); + + return KErrNone; + } + +/** + Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization + with V Sync so it will take affect in the next V Sync after that) and also set the Legacy Buffer as the buffer to + be posted next.Layer 0 is associated with legacy buffer. + + @param aNode Pointer to the Composition buffer to post. +*/ +TInt DDisplayPddSyborg::PostLegacyBuffer() + { + __GCE_DEBUG_PRINT("DDisplayPddSyborg::PostLegacyBuffer() \n"); + + if(iPendingBuffer) + { + iPendingBuffer->iState = EBufferFree; + if (iPendingBuffer->iType == EBufferTypeUser) + { + + RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrCancel); + } + else + { + iPendingBuffer->iFree = ETrue; + } + } + + + iLdd->iLegacyBuffer[0].iState = EBufferPending; + iLdd->iLegacyBuffer[0].iFree = EFalse; + iPendingBuffer = &iLdd->iLegacyBuffer[0]; + iPostFlag = ETrue; + + // Activate the posted buffer + WriteReg(DLcdPowerHandler::pLcd->iPortAddr, DLcdPowerHandler::FB_BASE, TSyborg::VideoRamPhys() ); + + /* Queue a DFC to complete the request*/ + iVSyncDfc.Enque(); + + return KErrNone; + } + +/** + Handles device specific operations when a close message has been sent to the Logical Channel. + +*/ +TInt DDisplayPddSyborg::CloseMsg() + { + __GCE_DEBUG_PRINT("DDisplayPddSyborg::CloseMsg()\n"); + + iPendingBuffer = NULL; + iActiveBuffer = NULL; + + iVSyncDfc.Cancel(); + return KErrNone; + } + +/** + Called by the LDD's DoCreate function to handle the device specific part of opening the channel. + (DoCreate is called by RDisplayChannel::Open) + + @param aUnit The screen unit + + @return KErrNone if successful; or one of the other system wide error codes. +*/ +TInt DDisplayPddSyborg::CreateChannelSetup(TInt aUnit) + { + __GCE_DEBUG_PRINT("DDisplayPddSyborg::CreateChannelSetup\n"); + + iScreenInfo = DLcdPowerHandler::pLcd->iVideoInfo; + iLdd->iUnit = aUnit; + + iLdd->iDisplayInfo.iAvailableRotations = RDisplayChannel::ERotationNormal; + iLdd->iDisplayInfo.iNormal.iOffsetBetweenLines = iScreenInfo.iOffsetBetweenLines; + iLdd->iDisplayInfo.iNormal.iHeight = iScreenInfo.iSizeInPixels.iHeight; + iLdd->iDisplayInfo.iNormal.iWidth = iScreenInfo.iSizeInPixels.iWidth; + iLdd->iDisplayInfo.iNumCompositionBuffers = KDisplayCBMax; + iLdd->iDisplayInfo.iBitsPerPixel = iScreenInfo.iBitsPerPixel; + iLdd->iDisplayInfo.iRefreshRateHz = 60; + + + switch (iScreenInfo.iBitsPerPixel) + { + case 16: + iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatRGB_565; + break; + case 24: + iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatRGB_888; + break; + case 32: + iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatARGB_8888; + break; + default: + iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatUnknown; + break; + } + + iLdd->iCurrentRotation = RDisplayChannel::ERotationNormal; + + // Open shared chunk to the composition framebuffer + + DChunk* chunk = 0; + TLinAddr chunkKernelAddr = 0; + TUint32 chunkMapAttr = 0; + + // round to twice the page size + TUint round = 2*Kern::RoundToPageSize(DLcdPowerHandler::pLcd->iSize); + + __GCE_DEBUG_PRINT2("DDisplayPddSyborg::CreateChannelSetup DLcdPowerHandler::pLcd->iSize = %d\n", DLcdPowerHandler::pLcd->iSize ); + + TChunkCreateInfo info; + info.iType = TChunkCreateInfo::ESharedKernelMultiple; + info.iMaxSize = round; + info.iMapAttr = EMapAttrFullyBlocking; + info.iOwnsMemory = EFalse; + info.iDestroyedDfc = 0; + + TInt r = Kern::ChunkCreate(info, chunk, chunkKernelAddr, chunkMapAttr); + + __GCE_DEBUG_PRINT2("CreateChannelSetup:ChunkCreate called for composition chunk. Set iChunkKernelAddr = %08x\n", chunkKernelAddr ); + + if( r == KErrNone) + { + // map our chunk + r = Kern::ChunkCommitPhysical(chunk, 0,round , DLcdPowerHandler::pLcd->iCompositionPhysical); + __GCE_DEBUG_PRINT2("Mapping chunk %d", r); + if(r != KErrNone) + { + Kern::ChunkClose(chunk); + } + } + + if ( r!= KErrNone) + { + return r; + } + + iChunk = chunk; + + // init CB 0 + iLdd->iCompositionBuffer[0].iType = EBufferTypeComposition; + iLdd->iCompositionBuffer[0].iBufferId = 0; + iLdd->iCompositionBuffer[0].iFree = ETrue; + iLdd->iCompositionBuffer[0].iState = EBufferFree; + iLdd->iCompositionBuffer[0].iAddress = chunkKernelAddr; + iLdd->iCompositionBuffer[0].iPhysicalAddress = Epoc::LinearToPhysical(chunkKernelAddr); + iLdd->iCompositionBuffer[0].iChunk = chunk; + iLdd->iCompositionBuffer[0].iHandle = 0; + iLdd->iCompositionBuffer[0].iOffset = 0; + iLdd->iCompositionBuffer[0].iSize = DLcdPowerHandler::pLcd->iSize; + iLdd->iCompositionBuffer[0].iPendingRequest = 0; + + // init CB 1 + iLdd->iCompositionBuffer[1].iType = EBufferTypeComposition; + iLdd->iCompositionBuffer[1].iBufferId = 1; + iLdd->iCompositionBuffer[1].iFree = ETrue; + iLdd->iCompositionBuffer[1].iState = EBufferFree; + iLdd->iCompositionBuffer[1].iAddress = chunkKernelAddr + DLcdPowerHandler::pLcd->iSize; + iLdd->iCompositionBuffer[1].iPhysicalAddress = Epoc::LinearToPhysical(chunkKernelAddr + DLcdPowerHandler::pLcd->iSize); + iLdd->iCompositionBuffer[1].iChunk = chunk; + iLdd->iCompositionBuffer[1].iHandle = 0; + iLdd->iCompositionBuffer[1].iOffset = DLcdPowerHandler::pLcd->iSize; + iLdd->iCompositionBuffer[1].iSize = DLcdPowerHandler::pLcd->iSize; + iLdd->iCompositionBuffer[1].iPendingRequest = 0; + + iLdd->iCompositionBuffIdx = 0; + //Use the same DFC queue created by the DLcdPowerHandler so all hardware accesses are executed under the same DFC thread. + iDfcQ= DLcdPowerHandler::pLcd->iDfcQ; + + // Set the Post DFC. + iVSyncDfc.SetDfcQ(iDfcQ); + + + return KErrNone; + } + +/** +Detect whether a post operation is pending +*/ +TBool DDisplayPddSyborg::PostPending() + { + return (iPendingBuffer != NULL); + } + +/** + Return the DFC queue to be used for this device. + */ +TDfcQue * DDisplayPddSyborg::DfcQ(TInt aUnit) + { + return iDfcQ; + } + +void DDisplayPddSyborg::VSyncDfcFn(TAny* aChannel) + { + DDisplayPddSyborg * channel =(DDisplayPddSyborg*)aChannel; + + if (channel->iPostFlag) + { + channel->iPostFlag = EFalse; + + if (channel->iActiveBuffer) + { + //When a User buffer is registered its iFree member becomes EFalse and Deregister sets it + //back to ETrue. Composition and Legacy buffers are not free when they are in the pending or + //active state. + if (channel->iActiveBuffer->iType == EBufferTypeUser) + { + channel->RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrNone); + } + else + { + channel->iActiveBuffer->iFree = ETrue; + } + + channel->iActiveBuffer->iState = EBufferFree; + + + //If no buffer was available during a call to GetCompositionBuffer the active buffer has + //been returned as the next available one, so we must set the buffer to the proper state before we + //send the notification. + TInt pendingIndex = channel->iLdd->iPendingIndex[RDisplayChannel::EReqGetCompositionBuffer]; + if(channel->iLdd->iPendingReq[RDisplayChannel::EReqGetCompositionBuffer][pendingIndex].iTClientReq) + { + if(channel->iLdd->iPendingReq[RDisplayChannel::EReqGetCompositionBuffer][pendingIndex].iTClientReq->IsReady()) + { + channel->iActiveBuffer->iState = EBufferCompose; + channel->RequestComplete(RDisplayChannel::EReqGetCompositionBuffer,KErrNone); + } + + } + + channel->iActiveBuffer = NULL; + } + + if (channel->iPendingBuffer) + { + __GCE_DEBUG_PRINT2("DDisplayPddSyborg::VSyncDfcFn moving pending buffer at address %08x to the active state\n", channel->iPendingBuffer->iAddress); + channel->iActiveBuffer = channel->iPendingBuffer; + channel->iActiveBuffer->iState = EBufferActive; + channel->iPendingBuffer = NULL; + + channel->RequestComplete(RDisplayChannel::EReqWaitForPost, KErrNone); + } + } + } +//***************************************************************** +//DDisplayPddFactory +//*****************************************************************/ + + +/** + Constructor +*/ +DDisplayPddFactory::DDisplayPddFactory() + { + __GCE_DEBUG_PRINT("DDisplayPddFactory::DDisplayPddFactory()\n"); + + iVersion = TVersion(KDisplayChMajorVersionNumber, + KDisplayChMinorVersionNumber, + KDisplayChBuildVersionNumber); + } + +/** + PDD factory function. Creates a PDD object. + + @param aChannel A pointer to an PDD channel object which will be initialised on return. + + @return KErrNone if object successfully allocated, KErrNoMemory if not. +*/ +TInt DDisplayPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer) + { + DDisplayPddSyborg *device= new DDisplayPddSyborg() ; + aChannel=device; + if (!device) + { + return KErrNoMemory; + } + return KErrNone; + } + + +/** + Set the Pdd name and return error code +*/ +TInt DDisplayPddFactory::Install() + { + __GCE_DEBUG_PRINT("DDisplayPddFactory::Install() \n"); + + TBuf<32> name(RDisplayChannel::Name()); + _LIT(KPddExtension,".pdd"); + name.Append(KPddExtension); + return SetName(&name); + } + + +void DDisplayPddFactory::GetCaps(TDes8& /*aDes*/) const + { + //Not supported + } + + +/** + Validate version and number of units. +*/ +TInt DDisplayPddFactory::Validate(TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& aVer) + { + if (!Kern::QueryVersionSupported(iVersion,aVer)) + { + return KErrNotSupported; + } + + if (aUnit != 0) + { + return KErrNotSupported; + } + + return KErrNone; + } + +DECLARE_EXTENSION_PDD() +/** + "Standard PDD" entrypoint.Creates PDD factory when Kern::InstallPhysicalDevice is called + + @return pointer to the PDD factory object. +*/ + { + __GCE_DEBUG_PRINT("DECLARE_EXTENSION_PDD()\n"); + return new DDisplayPddFactory ; + } + + +DECLARE_STANDARD_EXTENSION() +{ + TInt r = KErrNoMemory; + DLcdPowerHandler* pH=new DLcdPowerHandler; + if(pH) + { + r = pH->Create(); + if ( r == KErrNone) + { + TInt r = Kern::DfcQCreate(pH->iDfcQ, 29 , &KLitLcd); + + if(r!=KErrNone) + { + return r; + } + + DDisplayPddFactory * device = new DDisplayPddFactory; + + if (device==NULL) + { + r=KErrNoMemory; + } + else + { + r=Kern::InstallPhysicalDevice(device); + } + + #ifdef CPU_AFFINITY_ANY + NKern::ThreadSetCpuAffinity((NThread*) pH->iDfcQ->iThread, KCpuAffinityAny); + #endif + + __KTRACE_OPT(KEXTENSION,Kern::Printf("Installing the display device from the kernel extension returned with error code %d",r)); + + } + } + + return r; +} diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/svpframebuffer/svpframebuffer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/svpframebuffer/svpframebuffer.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,301 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Accenture Ltd - Syborg framebuffer improvements, now auto determines frame size from board model, performance and memory improvements +* +* Description: Minimalistic frame buffer driver +* +*/ + +#ifndef _SVPFRAMEBUFFER_H +#define _SVPFRAMEBUFFER_H + +#include + +#include +#include + +#define __SVPFRAMEBUFFER_DEBUG + +#ifdef __SVPFRAMEBUFFER_DEBUG + +#define __GCE_DEBUG_PRINT(a) Kern::Printf(a) +#define __GCE_DEBUG_PRINT2(a,b) Kern::Printf(a,b) + +#else + +#define __GCE_DEBUG_PRINT(a) +#define __GCE_DEBUG_PRINT2(a,b) + +#endif + +// Macro to calculate the screen buffer size +// aBpp is the number of bits-per-pixel, aPpl is the number of pixels per line and aLpp number of lines per panel +#define FRAME_BUFFER_SIZE(aBpp,aPpl,aLpp) ((aBpp/8)*aPpl*aLpp) + +_LIT(KLitLcd,"SYBORG_FB"); + + +const TInt KConfigLcdWidthInTwips = 1996; +const TInt KConfigLcdHeightInTwips = 3550; + +const TBool KConfigIsMono = 0; +const TBool KConfigIsPalettized = 0; +const TInt KCOnfigOffsetToFirstPixel = 0; +const TBool KConfigPixelOrderRGB = 0; +const TBool KConfigPixelOrderLandscape = 1; +const TInt KConfigLcdDisplayMode = 2; + +const TInt KConfigOffsetToFirstPixel =0; + +const TInt KConfigLcdNumberOfDisplayModes = 3; + + +const TInt KConfigBitsPerPixel = 32; + + +const TInt KVSyncDfcPriority = 7 ; //priority of DFC within the queue (0 to 7, where 7 is highest) + +/********************************************************************/ +/* Class Definition */ +/********************************************************************/ +/** + * This class defines a callback mechanism that is used by a resource user to specify its callback. It contains a + * function pointer and data pointer. The function pointer specifies the user callback function to be invoked by the + * resource while the data pointer specifies the data to be passed to the callback function. + */ +class TLcdUserCallBack + { +public: + // The constructor for the callback mechanism. + TLcdUserCallBack(TInt (*aFunction)(TUint aResID, TAny* aPtr), TAny* aPtr) + + { + iCbFn = aFunction; + iDataPtr = aPtr; + } + +public: + // The callback function pointer. + TInt (*iCbFn)(TUint aResID, TAny* aPtr); + + // Pointer to the data structure to be passed to the callback function. + TAny *iDataPtr; + }; + +class DLcdPowerHandler : public DPowerHandler +{ +public: // from DPowerHandler + void PowerDown(TPowerState); + void PowerUp(); +public: // to prevent a race condition with WServer trying to power up/down at the same time + void PowerUpDfc(); + void PowerDownDfc(); +public: + DLcdPowerHandler(); + TInt Create(); + void DisplayOn(); + void DisplayOff(); + TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2); + + void PowerUpLcd(TBool aSecure); + void PowerDownLcd(); + + void ScreenInfo(TScreenInfoV01& aInfo); + void WsSwitchOnScreen(); + void WsSwitchOffScreen(); + void HandleMsg(TMessageBase* aMsg); + void SwitchDisplay(TBool aSecure); + +private: + TInt GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure); + TInt GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo); + TInt SetDisplayMode(TInt aMode); + TInt AllocateFrameBuffer(); + +public: + IMPORT_C static TInt RegisterCallback(TLcdUserCallBack* aCbPtr); + IMPORT_C static void DeRegisterCallback(TLcdUserCallBack* aCbPtr); + +private: + TBool iDisplayOn; + DPlatChunkHw* iChunk; + DPlatChunkHw* iSecureChunk; + TBool iWsSwitchOnScreen; + TBool iSecureDisplay; + +public: + TDfcQue* iDfcQ; + TMessageQue iMsgQ; // to prevent a race condition with Power Manager trying to power up/down at the same time + TDfc iPowerUpDfc; + TDfc iPowerDownDfc; + +private: + NFastMutex iLock; + TPhysAddr ivRamPhys; + TPhysAddr iSecurevRamPhys; + TLcdUserCallBack * iAppCallBk[2]; + +public: + TVideoInfoV01 iVideoInfo; + TVideoInfoV01 iSecureVideoInfo; + TInt iSize; + TLinAddr iPortAddr; + TPhysAddr iCompositionPhysical; + static DLcdPowerHandler * pLcd; + +enum { + FB_ID = 0, + FB_BASE = 1, + FB_HEIGHT = 2, + FB_WIDTH = 3, + FB_ORIENTATION = 4, + FB_BLANK = 5, + FB_INT_MASK = 6, + /* begin new interface */ + FB_INTERRUPT_CAUSE = 7, + FB_BPP = 8, + FB_COLOR_ORDER = 9, + FB_BYTE_ORDER = 10, + FB_PIXEL_ORDER = 11, + FB_ROW_PITCH = 12, + FB_ENABLED = 13, + FB_PALETTE_START = 0x400 >> 2, + FB_PALETTE_END = FB_PALETTE_START+256-1, + /* end new interface */ + }; + +#define FB_INT_VSYNC (1U << 0) +#define FB_INT_BASE_UPDATE_DONE (1U << 1) + +}; + +class DDisplayPddSyborg : public DDisplayPdd + { + + public: + DDisplayPddSyborg(); + ~DDisplayPddSyborg(); + + /** + Called by the LDD to handle the device specific part of switching to Legacy mode. + + @return KErrNone if successful; or one of the other system wide error codes. + */ + virtual TInt SetLegacyMode(); + + /** + Called by the LDD to handle the device specific part of switching to GCE mode. + + @return KErrNone if successful; or one of the other system wide error codes. + */ + virtual TInt SetGceMode(); + + /** + Called by the LDD to handle the device specific part of setting the rotation. + + @return KErrNone if successful; or one of the other system wide error codes. + */ + virtual TInt SetRotation(RDisplayChannel::TDisplayRotation aRotation); + + /** + Called by the LDD to handle the device specific part of posting a User Buffer. + + @return KErrNone if successful; or one of the other system wide error codes. + */ + virtual TInt PostUserBuffer(TBufferNode* aNode); + + /** + Called by the LDD to handle the device specific part of posting a Composition Buffer + + @return KErrNone if successful; or one of the other system wide error codes. + */ + virtual TInt PostCompositionBuffer(TBufferNode* aNode); + + /** + Called by the LDD to handle the device specific part of posting the Legacy Buffuer + + @return KErrNone if successful; or one of the other system wide error codes. + */ + virtual TInt PostLegacyBuffer(); + + /** + Called by the LDD to handle device specific cleanup operations when a channel is closed. + + @return KErrNone if successful; or one of the other system wide error codes. + */ + virtual TInt CloseMsg(); + + /** + Called by the LDD to handle device specific initialisation tasks when a channel is opened. + + @param aUnit The screen/hardware unit number. + @return KErrNone if successful; or one of the other system wide error codes. + */ + virtual TInt CreateChannelSetup(TInt aUnit); + + /** + Called by the LDD in order to detect whether a post operation is pending. This type of + information is specific to the actual physical device. + + @return ETrue if a Post operation is pending otherwise EFalse. + */ + virtual TBool PostPending(); + + /** + Called by the LDD to retrieve the DFC Queue created in the PDD. + + @param aUnit The screen/hardware unit number. + @return A pointer to the TDfcQue object created in the PDD. + */ + virtual TDfcQue* DfcQ(TInt aUnit); + +public: + static void VSyncDfcFn(TAny* aChannel); + +private: + TDfcQue* iDfcQ; + + //generic display info + TVideoInfoV01 iScreenInfo; + + //Pointer to a buffer in the Pending state + TBufferNode* iPendingBuffer; + + //Pointer to a buffer in the Active state + TBufferNode* iActiveBuffer; + + DChunk * iChunk; + TLcdUserCallBack* iLcdCallback; + + public: + TDfc iVSyncDfc; + }; + + +/** + PDD Factory class + */ + +class DDisplayPddFactory : public DPhysicalDevice + { +public: + DDisplayPddFactory(); + + virtual TInt Install(); + virtual void GetCaps(TDes8& aDes) const; + virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); + virtual TInt Validate(TInt aDeviceType, const TDesC8* anInfo, const TVersion& aVer); + }; + +#endif diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/svpframebuffer/svpframebuffer.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/svpframebuffer/svpframebuffer.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include +#include "kernel/kern_ext.mmh" + +TARGET VariantTarget(svpframebuffer,dll) +TARGETTYPE kext + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) +SYSTEMINCLUDE AsspNKernIncludePath +SYSTEMINCLUDE . + +SOURCEPATH . +SOURCE svpframebuffer.cpp + +LIBRARY PlatformLib + +EPOCALLOWDLLDATA + +UID 0x1000008d 0x100039e8 +VENDORID 0x70000001 + +ROMTARGET lcd.dll + +CAPABILITY all diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/svphostfs/driver/svphostfsdriver.cpp --- a/baseport/syborg/svphostfs/driver/svphostfsdriver.cpp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/svphostfs/driver/svphostfsdriver.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -416,7 +416,14 @@ if (KErrNone != err) { - DP("Error %d from DoRequest", err); + + if (err == KErrNotSupported) + { + err = KErrNone; // trap KErrNotSupported + } + + DP("Error %d from DoRequest %d", err, aReqNo); + } return err; @@ -437,6 +444,12 @@ if (KErrNone != err) { + + if (err == KErrNotSupported) + { + err = KErrNone; // trap KErrNotSupported + } + DP("** (SVPHOSTFSDRIVER) Error %d from control function", err); } @@ -501,7 +514,16 @@ SVPWriteReg(device, EArg2, info.iFlags); SVPInvoke(device, RSVPHostFsDriver::EMkDir); - return SVPReadReg(device, EResult); + + //return SVPReadReg(device, EResult); + + err = SVPReadReg(device, EResult); + + if(err == KErrPathNotFound) + err = KErrNotFound; + + return err; + } @@ -637,7 +659,20 @@ SVPWriteReg(device, EArg1, info.iLength); SVPInvoke(device, RSVPHostFsDriver::EEntry); - RET_IF_ERROR(err, SVPReadReg(device, EResult)); + + //RET_IF_ERROR(err, SVPReadReg(device, EResult)); + + err = SVPReadReg(device, EResult); + + if(err!=KErrNone) + { + if(err == KErrPathNotFound) + err = KErrNotFound; + + return err; + } + + TUint32 att = SVPReadReg(device, EArg0); TUint32 modified = SVPReadReg(device, EArg1); @@ -690,7 +725,20 @@ SVPWriteReg(device, EArg1, info.iLength); SVPInvoke(device, RSVPHostFsDriver::EDirOpen); - RET_IF_ERROR(err, SVPReadReg(device, EResult)); + + //RET_IF_ERROR(err, SVPReadReg(device, EResult)); + + err = SVPReadReg(device, EResult); + + if(err!=KErrNone) + { + + if(err==KErrPathNotFound) + err=KErrNotFound; + + return err; + } + // handle is in arg 0 TUint32 handle = SVPReadReg(device, EArg0); @@ -719,7 +767,20 @@ SVPWriteReg(device, EArg3, info.iOpen); SVPInvoke(device, RSVPHostFsDriver::EFileOpen); - RET_IF_ERROR(err, SVPReadReg(device, EResult)); + + //RET_IF_ERROR(err, SVPReadReg(device, EResult)); + + err = SVPReadReg(device, EResult); + + if(err!=KErrNone) + { + if(err == KErrPathNotFound) + err = KErrNotFound; + + return err; + } + + TUint32 handle = SVPReadReg(device, EArg0); TUint32 att = SVPReadReg(device, EArg1); @@ -797,7 +858,20 @@ SVPWriteReg(device, EArg3, info.iLength); SVPInvoke(device, RSVPHostFsDriver::EFileWrite); - RET_IF_ERROR(err, SVPReadReg(device, EResult)); + + // RET_IF_ERROR(err, SVPReadReg(device, EResult)); + + err = SVPReadReg(device, EResult); + + if(err!=KErrNone) + { + if(err == KErrPathNotFound) + err = KErrNotFound; + + return err; + } + + TUint32 len = SVPReadReg(device, EArg0); @@ -831,7 +905,9 @@ { DP("** (SVPHOSTFSDRIVER) DSVPHostFsChannel::FileSetEntry()"); - return KErrNotSupported; + + return KErrNone; + } TInt DSVPHostFsChannel::DirClose(TUint32 aDrive, TUint32 aHandle) diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/svphostfs/fs/rsvphostfsdriver.cpp --- a/baseport/syborg/svphostfs/fs/rsvphostfsdriver.cpp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/svphostfs/fs/rsvphostfsdriver.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -10,6 +10,7 @@ * Nokia Corporation - initial contribution. * * Contributors: +* Sosco - bug fixes * * Description: * @@ -92,6 +93,19 @@ TInt RSVPHostFsDriver::FileClose(TUint32 aDrive, TUint32 aHandle) { DP(_L("** (rsvphostfsdriver.cpp) RSVPHostFsDriver::FileClose()")); + + // If attempt is made to access a file which does + // not exist, it will not give a handle to close afterwards. + // Attempting to call FileClose on this with an invalid handle + // results in the error code KErrBadHandle (-8) being returned. + // Some UI's cannot cope properly with this error code, resulting + // in various servers repeatedly closing and reopening. To prevent + // this,we trap it here and return KErrNone as though the call + // completed properly without error. + if (aHandle == 0) + return KErrNone; // Bad handle, so exit immediately with KErrNone + else + return DoSVPRequest(EFileClose, (TAny *)aDrive, (TAny *)aHandle); } @@ -140,6 +154,20 @@ TInt RSVPHostFsDriver::DirClose(TUint32 aDrive, TUint32 aHandle) { DP(_L("** (rsvphostfsdriver.cpp) RSVPHostFsDriver::DirClose()")); + + + // If attempt is made to read a directory which does + // not exist, it will not give a handle to close afterwards. + // Attempting to call DirClose on this with an invalid handle + // results in the error code KErrBadHandle (-8) being returned. + // Some UI's cannot cope properly with this error code, resulting + // in various servers repeatedly closing and reopening. To prevent + // this,we trap it here and return KErrNone as though the call + // completed properly without error. + if (aHandle == 0) + return KErrNone; // Bad handle, so exit immediately with KErrNone + else + return DoSVPRequest(EDirClose, (TAny *)aDrive, (TAny *)aHandle); } diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/svphostfs/fs/svphostdir.cpp --- a/baseport/syborg/svphostfs/fs/svphostdir.cpp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/svphostfs/fs/svphostdir.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -116,9 +116,14 @@ } iPending=EFalse; anEntry=iEntry; - if ((iFullName.NameAndExt()==_L("*.*") || anEntry.iName.MatchF(iFullName.NameAndExt())!=KErrNotFound) - && Mount().MatchEntryAtt(anEntry.iAtt&KEntryAttMaskSupported,iAtt)) - { + + + if (Mount().MatchEntryAtt(anEntry.iAtt&KEntryAttMaskSupported,iAtt) == EFalse) + continue; + + if (iFullName.NameAndExt()==_L("*.*") || anEntry.iName.MatchF(iFullName.NameAndExt())!=KErrNotFound) + + { if (MatchUid()) { TParse fileName; diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/svphostfs/fs/svphostmnt.cpp --- a/baseport/syborg/svphostfs/fs/svphostmnt.cpp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/svphostfs/fs/svphostmnt.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -23,7 +23,11 @@ #include "svphostfsy.h" #define HOST_SVP_DRIVE_SIZE 1024*1024*1024 -#define HOST_SVP_DRIVE_FREE_SIZE 10*1024*1024 + +// Fixed low mass-memory warning at startup +//#define HOST_SVP_DRIVE_FREE_SIZE 10*1024*1024 +#define HOST_SVP_DRIVE_FREE_SIZE 100*1024*1024 + LOCAL_C TInt GetMediaSize(TInt /*aDriveNumber*/,TInt64& aSize,TInt64& aFree) // diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/svphostfs/svphostfs.mmp --- a/baseport/syborg/svphostfs/svphostfs.mmp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/svphostfs/svphostfs.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -22,6 +22,7 @@ LIBRARY euser.lib efsrv.lib efile.lib hal.lib SYSTEMINCLUDE inc SYSTEMINCLUDE /epoc32/include +OS_LAYER_SYSTEMINCLUDE CAPABILITY DISKADMIN ALLFILES VENDORID 0x70000001 diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/svphostfs/svphostfsdriver.mmp --- a/baseport/syborg/svphostfs/svphostfsdriver.mmp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/svphostfs/svphostfsdriver.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -24,6 +24,7 @@ systeminclude inc systeminclude ../svpplatform/libfdt systeminclude /epoc32/include/stdapis +OS_LAYER_LIBC_SYSTEMINCLUDE target VariantTarget(svphostfsdriver,ldd) linkas svphostfsdriver.ldd diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/svphostfs/svphostfsstart.mmp --- a/baseport/syborg/svphostfs/svphostfsstart.mmp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/svphostfs/svphostfsstart.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -22,6 +22,7 @@ LIBRARY euser.lib efsrv.lib efile.lib hal.lib SYSTEMINCLUDE inc SYSTEMINCLUDE /epoc32/include +OS_LAYER_SYSTEMINCLUDE CAPABILITY DISKADMIN ALLFILES VENDORID 0x70000001 diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/svphostfs/svphostfsy.mmp --- a/baseport/syborg/svphostfs/svphostfsy.mmp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/svphostfs/svphostfsy.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -24,6 +24,7 @@ SYSTEMINCLUDE inc SYSTEMINCLUDE /epoc32/include +OS_LAYER_SYSTEMINCLUDE LIBRARY efsrv.lib euser.lib hal.lib LIBRARY efile.lib diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/svpplatform/fdt.mmp --- a/baseport/syborg/svpplatform/fdt.mmp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/svpplatform/fdt.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -20,6 +20,7 @@ systeminclude libfdt systeminclude /epoc32/include/stdapis +OS_LAYER_LIBC_SYSTEMINCLUDE sourcepath libfdt diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/svpsnapdriver/snapapp.mmp --- a/baseport/syborg/svpsnapdriver/snapapp.mmp Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/svpsnapdriver/snapapp.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -20,7 +20,7 @@ SOURCEPATH src SOURCE snapapp.cpp rsvpsnapdriver.cpp LIBRARY euser.lib efsrv.lib -SYSTEMINCLUDE /epoc32/include +OS_LAYER_SYSTEMINCLUDE CAPABILITY TCB DISKADMIN ALLFILES VENDORID 0x70000001 diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/syborg.dtb Binary file baseport/syborg/syborg.dtb has changed diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/syborg.dts --- a/baseport/syborg/syborg.dts Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/syborg.dts Tue Apr 06 17:00:22 2010 +0100 @@ -50,6 +50,8 @@ }; framebuffer@0 { compatible = "syborg,framebuffer"; + width = <168>; + height = <280>; reg = ; interrupts = <4>; interrupt-parent = <&intc>; @@ -113,9 +115,15 @@ interrupts = ; interrupt-parent = <&intc>; }; + usbtest@0 { + compatible = "syborg,usbtest"; + reg = ; + interrupts = ; + interrupt-parent = <&intc>; + }; platform@0 { compatible = "syborg,platform"; - reg = ; + reg = ; }; }; }; diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/syborg.oby --- a/baseport/syborg/syborg.oby Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/syborg.oby Tue Apr 06 17:00:22 2010 +0100 @@ -35,10 +35,17 @@ define VARIANT syborg define VARID SYBORG_L1 define ASSP_DIR EPOCROOT##epoc32\release\syborg -define ROMMEGS 15 /* !! HEX !! */ + +// increased size of ROM, due to overflow +//define ROMMEGS 15 /* !! HEX !! */ + +define ROMMEGS 50 /* !! HEX !! */ define PLATFORM_NAME syborg +#define BASEPORT_DRV +#define COLOR +#undef SYMBIAN_EXCLUDE_SCDV -#define COLOR + REM defines for IrDA options REM Uncomment the line below to enable IrDA to use a Jeteye ESI09680 pod with serial card adapter @@ -50,7 +57,9 @@ define BLUETOOTH_ESK bt_port2.esk REM Define whether or not to include USB client support: -//#define EUSBC + +#define EUSBC + ROMBUILD_OPTION -no-header diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/variant.mmh --- a/baseport/syborg/variant.mmh Tue Apr 06 16:31:41 2010 +0100 +++ b/baseport/syborg/variant.mmh Tue Apr 06 17:00:22 2010 +0100 @@ -15,6 +15,8 @@ * */ +#include + //macro __CPU_ARM926J__ //#define __CPU__ ARM926EJ-S @@ -119,6 +121,11 @@ systeminclude /epoc32/include/memmodel/epoc/multiple systeminclude /epoc32/include/memmodel/epoc/multiple/arm +SYMBIAN_BASE_SYSTEMINCLUDE(memmodel/epoc/mmubase) +SYMBIAN_BASE_SYSTEMINCLUDE(memmodel/epoc/multiple) +SYMBIAN_BASE_SYSTEMINCLUDE(memmodel/epoc/multiple/arm) +OS_LAYER_SYSTEMINCLUDE + systeminclude ../../../../os/kernelhwsrv/driversupport/socassp/interface // Uncomment for T_USERCOMDEB test diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/webcamera/webcamera_app.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/webcamera/webcamera_app.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,115 @@ +/* +* Copyright (c) 2010 ISB. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* ISB - initial contribution. +* +* Contributors: +* +* Description: USB driver for test +* +*/ + +#include +#include + +#include +#define DP(format...) RDebug::Printf(format) + +LOCAL_D RTest test(_L("WebcameraDevice_TEST")); + +//Wins—pƒ_ƒ~[‚È‚Ì‚ÅŽÀ‹@‚łͳŽ®‚È‚à‚Ì‚ðŽg—p‚·‚é +_LIT(KWebcameraPddFileName, "webcamera.pdd"); +_LIT(KWebcameraLddFileName, "ewebcamera.ldd"); + +GLDEF_C TInt E32Main() + { + test.Title(); + TInt r; + + test.Start(_L("Load Physical Device")); + r=User::LoadPhysicalDevice(KWebcameraPddFileName); + test(r==KErrNone || r==KErrAlreadyExists); + + test.Next(_L("Load Logical Device")); + r=User::LoadLogicalDevice(KWebcameraLddFileName); + test(r==KErrNone || r==KErrAlreadyExists); +// __KHEAP_MARK; + +// test.Next(_L("Open Device")); +// RDevice device; +// r=device.Open(RWebcameraDevice::Name()); +// test(r==KErrNone); + + //test.Next(_L("Close Device")); + //device.Close(); + + test.Next(_L("Open Logical Channel")); + RWebcameraDevice ldd; + r=ldd.Open(); + test(r==KErrNone); + + test.Next(_L("Check access by wrong client")); + RWebcameraDevice ldd2=ldd; + r=ldd2.Duplicate(RThread(),EOwnerProcess); + test(r==KErrAccessDenied); + + test.Next(_L("Check handle duplication")); + ldd2=ldd; + r=ldd2.Duplicate(RThread(),EOwnerThread); + test(r==KErrNone); + ldd2.Close(); + + test.Next(_L("ReceiveData")); + TRequestStatus status; + HBufC8 * buffer = HBufC8::NewL(BUFSIZE); + TPtr8 itempPtr(buffer->Des()); + itempPtr.SetLength(0); + ldd.StartViewFinder(status,itempPtr); + + test.Next(_L("ReceiveDataCancel")); + ldd.StopViewFinder(); + User::WaitForRequest(status); + r=status.Int(); + test(r==KErrNone); + + itempPtr.SetLength(0); + ldd.StartViewFinder(status,itempPtr); + User::WaitForRequest(status); + r=status.Int(); + test(r==KErrNone); + + test.Next(_L("CaptureData")); + HBufC8 * buffer1 = buffer; + TPtr8 itempPtr1(buffer1->Des()); + itempPtr1.SetLength(0); + ldd.Capture(status,itempPtr1); + User::WaitForRequest(status); + r=status.Int(); + test(r==KErrNone); + + test.Next(_L("Close Logical Channel")); + ldd.Close(); + +// __KHEAP_MARKEND; + + test.Next(_L("Unload Logical Device")); + r=User::FreeLogicalDevice(RWebcameraDevice::Name()); + test(r==KErrNone); + + test.Next(_L("Unload Physical Device")); + TName pddName(RWebcameraDevice::Name()); + _LIT(KVariantExtension,".pdd"); + pddName.Append(KVariantExtension); + r=User::FreePhysicalDevice(pddName); + test(r==KErrNone); + + test.End(); + + return(0); + } diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/webcamera/webcamera_app.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/webcamera/webcamera_app.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2010 ISB. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* ISB - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +TARGET webcamera_app.exe +TARGETTYPE exe + +//UID 0x1000008d 0x101F399B //TODO:C³‚·‚é•K—v +VENDORID 0x70000001 + +CAPABILITY DISKADMIN ALLFILES + +SYSTEMINCLUDE /epoc32/include +SYSTEMINCLUDE /epoc32/include/platform + +SOURCEPATH . +SOURCE webcamera_app.cpp + +LIBRARY euser.lib \ No newline at end of file diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/webcamera/webcamera_device.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/webcamera/webcamera_device.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,94 @@ +/* +* Copyright (c) 2010 ISB. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* ISB - initial contribution. +* +* Contributors: +* +* Description: USB driver for test +* +*/ + +#ifndef __deviceBASE_H +#define __deviceBASE_H + +#include +#include +#include + + +class DWebcameraLogicalChannelBase : public DLogicalChannel +{ +public: + /** + Called by PDD from ISR to indicate that a get oneflame operation has completed. + */ + virtual void GetOneFlameComplete(TInt aResult)=0; + /** + call to the function if one Capture image is received. + */ + virtual void CaptureComplete(TInt aResult)=0; + /** + call to the function if one flame is received. + */ + /** + call to the function if one Capture image is received. + */ + virtual void DoCaptureComplete()=0; + +public: + /** + * pointer to client. + */ + DThread* iClient; +}; + +class DWebcameraDriverBase : public DBase +{ +public: + /** + Enumeration of stop modes. + */ + enum TUSBStopMode + { + USB_ViewerFinder =0, + USB_capture =1, + USB_cancel =2 + }; + /** + request. + */ + virtual TInt StartViewerFinder(TUint aBuffer,TInt aSize)=0; + /** + Enumeration of stop modes. + */ + virtual TInt StartCapture(TUint aBuffer,TInt aSize)=0; + /** + Enumeration of stop modes. + */ + virtual void Stop(TUSBStopMode aMode)=0; +//virtual void Caps(TDes8 &aCaps) const; + +public: + /** + * pointer to logic channel. + */ + DWebcameraLogicalChannelBase* iLdd; + /** + * Linear Addresses of Peripherals. + */ + TLinAddr iPortAddr; + /** + * interrupt number. + */ + TInt iIrq; + +}; + +#endif diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/webcamera/webcamera_driver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/webcamera/webcamera_driver.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,144 @@ +/* +* Copyright (c) 2010 ISB. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* ISB - initial contribution. +* +* Contributors: +* +* Description: USB driver for test +* +*/ +#ifndef __deviceIF_H__ +#define __deviceIF_H__ + +#include +#include + +#define BUFSIZE (100*1024) + +/** +User interface for 'WebcameraDevice' +Define of the RBusLogicalChannel that is used in the application +*/ +class RWebcameraDevice : public RBusLogicalChannel + { +public: + /** + Structure for holding driver capabilities information + */ + class TCaps + { + public: + TVersion iVersion; + }; + /** + Structure for holding driver configuration data + */ + class TConfig + { + public: + TInt iPddBufferSize; /**< Size of the PDD's data buffer (not modifiable) */ + //RArray iImageSizes /**< size the PDD support*/ //TODO:implement + }; + typedef TPckgBuf TConfigBuf; + +public: + /** + Opens a logical channel to the driver + + @return One of the system wide error codes. + */ + inline TInt Open(); + /** + Gets the current configuration settings. + + @param aConfig A structure which will be filled with the configuration settings. + + @return KErrNone + */ + inline TInt GetConfig(TConfigBuf& aConfig); + /** + Sets the current configuration settings. + + @param aConfig The new configuration settings to be used. + + @return KErrInUse if there are outstanding data transfer requests. + KErrArgument if any configuration values are invalid. + KErrNone otherwise + */ + inline TInt SetConfig(const TConfigBuf& aConfig); + /** + Request data from device. + Only one send request may be pending at any time. + + @param aStatus The request to be signalled when the data has been sent. + The result value will be set to KErrNone on success; + or set to one of the system wide error codes when an error occurs. + @param aData A descriptor containing the data to send. + */ + inline void StartViewFinder(TRequestStatus& aStatus,TDes8& aBuffer); + /** + Cancels a previous getdata request. + */ + inline void StartViewFinderCancel(); + /** + Cancels a previous getdata request and notice device not to send data + */ + inline void StopViewFinder(); + /** + Request data(Capture data) from device. + Only one send request may be pending at any time. + + @param aStatus The request to be signalled when the data has been sent. + The result value will be set to KErrNone on success; + or set to one of the system wide error codes when an error occurs. + @param aData A descriptor containing the data to send. + */ + inline void Capture(TRequestStatus& aStatus,TDes8& aBuffer); + /** + Cancels a previous getCapturedata request. + */ + inline void CaptureCancel(); + /** + Returns the driver's name + */ + inline static const TDesC& Name(); + /** + Returns the version number of the driver + */ + inline static TVersion VersionRequired(); + +public: + /** + Enumeration of Control messages. + */ + enum TControl + { + EGetConfig, + ESetConfig + }; + /** + Enumeration of Request messages. + */ + enum TRequest + { + EStart, + ECapture, + ENumRequests, + EAllRequests = (1< + +#endif diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/webcamera/webcamera_driver.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/webcamera/webcamera_driver.inl Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,139 @@ +/* +* Copyright (c) 2010 ISB. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* ISB - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#ifndef __deviceIFI_H +#define __deviceIFI_H + +/** + Returns the driver's name +*/ +inline const TDesC& RWebcameraDevice::Name() + { + _LIT(KDriverName,"WebcameraDevice"); + return KDriverName; + } + +/** + Returns the version number of the driver +*/ +inline TVersion RWebcameraDevice::VersionRequired() + { + const TInt KMajorVersionNumber=1; + const TInt KMinorVersionNumber=1; + const TInt KBuildVersionNumber=0; + return TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); + } + +/* + NOTE: The following member functions would normally be exported from a seperate client DLL + but are included inline in this header file for convenience. +*/ + +#ifndef __KERNEL_MODE__ + +/** + Opens a logical channel to the driver + + @return One of the system wide error codes. +*/ +inline TInt RWebcameraDevice::Open() + { + return DoCreate(Name(),VersionRequired(),KNullUnit,NULL,NULL,EOwnerThread); + } + + +/** + Gets the current configuration settings. + + @param aConfig A structure which will be filled with the configuration settings. + + @return KErrNone +*/ +inline TInt RWebcameraDevice::GetConfig(TConfigBuf& aConfig) + { + return DoControl(EGetConfig,(TAny*)&aConfig); + } + + +/** + Sets the current configuration settings. + + @param aConfig The new configuration settings to be used. + + @return KErrInUse if there are outstanding data transfer requests. + KErrArgument if any configuration values are invalid. + KErrNone otherwise +*/ +inline TInt RWebcameraDevice::SetConfig(const TConfigBuf& aConfig) + { + return DoControl(ESetConfig,(TAny*)&aConfig); + } + +/** + Receives image from the device. + Only one receive request may be pending at any time. + + @param aStatus The request to be signalled when the data has been received. + The result value will be set to KErrNone on success; + or set to one of the system wide error codes when an error occurs. + @param aData A descriptor to which the received data will be written. +*/ +inline void RWebcameraDevice::StartViewFinder(TRequestStatus& aStatus,TDes8& aBuffer) + { + TInt length=BUFSIZE; + DoRequest(EStart,aStatus,(TAny*)&aBuffer,(TAny*)&length); + } + + +/** + Cancels a previous StartViewFinder request. +*/ +inline void RWebcameraDevice::StartViewFinderCancel() + { + DoCancel(1< +#include "webcamera_ldd.h" +#include + +#define DP(format...) Kern::Printf(format) + +_LIT(KDriver1PanicCategory,"WebcameraDevice"); + +/** + *Create Logic device. + * + */ +DECLARE_STANDARD_LDD() + { + DP("DECLARE_STANDARD_LDD()"); + return new DWebcameraLogicalDevice; + } + +/** + Constructor +*/ +DWebcameraLogicalDevice::DWebcameraLogicalDevice() + { + DP("DWebcameraLogicalDevice()"); + // Set version number for this device + iVersion=RWebcameraDevice::VersionRequired(); + // Indicate that we work with a PDD + iParseMask=KDeviceAllowPhysicalDevice; + } + +/** + Destructor +*/ +DWebcameraLogicalDevice::~DWebcameraLogicalDevice() + { + } + +/** + Second stage constructor for DDriver1Factory. + This must at least set a name for the driver object. + + @return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DWebcameraLogicalDevice::Install() + { + DP("DWebcameraLogicalDevice::Install()"); + + return SetName(&RWebcameraDevice::Name()); + } + +/** + Return the drivers capabilities. + Called in the response to an RDevice::GetCaps() request. + + @param aDes User-side descriptor to write capabilities information into +*/ +void DWebcameraLogicalDevice::GetCaps(TDes8& aDes) const + { + // Create a capabilities object + RWebcameraDevice::TCaps caps; + caps.iVersion = iVersion; + // Write it back to user memory + Kern::InfoCopy(aDes,(TUint8*)&caps,sizeof(caps)); + } + +/** + Called by the kernel's device driver framework to create a Logical Channel. + This is called in the context of the user thread (client) which requested the creation of a Logical Channel + (E.g. through a call to RBusLogicalChannel::DoCreate) + The thread is in a critical section. + + @param aChannel Set to point to the created Logical Channel + + @return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DWebcameraLogicalDevice::Create(DLogicalChannelBase*& aChannel) + { + DP("DWebcameraLogicalDevice::Create() start"); + aChannel = new DWebcameraLogicalChannel; + if(!aChannel) + return KErrNoMemory; + return KErrNone; + DP("DWebcameraLogicalDevice::Create() end"); + } + +/** + Constructor +*/ +DWebcameraLogicalChannel::DWebcameraLogicalChannel() + : iReceiveDataDfc(GetOneFlameDfc, this, 1) + ,iCaptureDfc(CaptureDfc,this,1) + { + DP("DWebcameraLogicalChannel::DWebcameraLogicalChannel() start"); + + // Get pointer to client threads DThread object + iClient=&Kern::CurrentThread(); + // Open a reference on client thread so it's control block can't dissapear until + // this driver has finished with it. + ((DObject*)iClient)->Open(); + + DP("DWebcameraLogicalChannel::DWebcameraLogicalChannel() end"); + } + +/** + Destructor +*/ +DWebcameraLogicalChannel::~DWebcameraLogicalChannel() + { + DP("DWebcameraLogicalChannel::~DWebcameraLogicalChannel() start"); + // Cancel all processing that we may be doing + DoCancel(RWebcameraDevice::EAllRequests); + if (iComm) + { + delete iComm; + } + if (iChunk) + { + Epoc::FreePhysicalRam(iPhysAddr, iSize); + } + // Close our reference on the client thread + Kern::SafeClose((DObject*&)iClient,NULL); + DP("DWebcameraLogicalChannel::~DWebcameraLogicalChannel() end"); + } + +/** + Called when a user thread requests a handle to this channel. +*/ +TInt DWebcameraLogicalChannel::RequestUserHandle(DThread* aThread, TOwnerType aType) + { + // Make sure that only our client can get a handle + if (aType!=EOwnerThread || aThread!=iClient) + return KErrAccessDenied; + return KErrNone; + } + +/** + Second stage constructor called by the kernel's device driver framework. + This is called in the context of the user thread (client) which requested the creation of a Logical Channel + (E.g. through a call to RBusLogicalChannel::DoCreate) + The thread is in a critical section. + + @param aUnit The unit argument supplied by the client + @param aInfo The info argument supplied by the client + @param aVer The version argument supplied by the client + + @return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DWebcameraLogicalChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer) + { + DP("DWebcameraLogicalChannel::DoCreate() start"); + if(!Kern::CurrentThreadHasCapability(ECapability_None,__PLATSEC_DIAGNOSTIC_STRING("Checked by Webcamera"))) + { + return KErrPermissionDenied; + } + // Check version + if (!Kern::QueryVersionSupported(RWebcameraDevice::VersionRequired(),aVer)) + { + return KErrNotSupported; + } + // Setup LDD for receiving client messages + SetDfcQ(Kern::DfcQue0()); + iMsgQ.Receive(); + // Associate DFCs with the same queue we set above to receive client messages on + iReceiveDataDfc.SetDfcQ(iDfcQ); + iCaptureDfc.SetDfcQ(iDfcQ); + // Give PDD a pointer to this channel + Pdd()->iLdd=this; + + //allocate Memory + iSize=Kern::RoundToPageSize(BUFSIZE); + TInt rtn=Epoc::AllocPhysicalRam(iSize, iPhysAddr); + if (rtn != KErrNone) + { + return rtn; + } + rtn=DPlatChunkHw::New(iChunk, iPhysAddr, iSize,EMapAttrUserRw|EMapAttrBufferedC); + if (rtn != KErrNone) + { + if (iPhysAddr) + { + Epoc::FreePhysicalRam(iPhysAddr, iSize); + } + return rtn; + } + iLAdr = reinterpret_cast(iChunk->LinearAddress()); + + iComm=HBuf8::New(BUFSIZE); + if (!iComm) + { + return KErrNotSupported; + } + iReceiveDataBuffer=iComm; + iCaptureBuffer=iComm; + + DP("DWebcameraLogicalChannel::DoCreate() end"); + return KErrNone; + } + +/** + Process a message for this logical channel. + This function is called in the context of a DFC thread. + + @param aMessage The message to process. + The iValue member of this distinguishes the message type: + iValue==ECloseMsg, channel close message + iValue==KMaxTInt, a 'DoCancel' message + iValue>=0, a 'DoControl' message with function number equal to iValue + iValue<0, a 'DoRequest' message with function number equal to ~iValue +*/ +void DWebcameraLogicalChannel::HandleMsg(TMessageBase* aMsg) + { + DP("DWebcameraLogicalChannel::HandleMsg() start"); + TThreadMessage& m=*(TThreadMessage*)aMsg; + + // Get message type + TInt id=m.iValue; + DP("id=%d",id); + + // Decode the message type and dispatch it to the relevent handler function... + if (id==(TInt)ECloseMsg) + { + DoCancel(RWebcameraDevice::EAllRequests); + m.Complete(KErrNone, EFalse); + return; + } + + if(m.Client()!=iClient) + { + Kern::ThreadKill(m.Client(), + EExitPanic, + ERequestFromWrongThread, + KDriver1PanicCategory); + m.Complete(KErrNone,ETrue); + return; + } + + if (id==KMaxTInt) + { + DoCancel(m.Int0()); + m.Complete(KErrNone,ETrue); + return; + } + + if (id<0) + { + // DoRequest + TRequestStatus* pS=(TRequestStatus*)m.Ptr0(); + TInt rtn =DoRequest(~id,pS,m.Ptr1(),aMsg); + + if (rtn != KErrNone) + Kern::RequestComplete(iClient,pS,rtn); + m.Complete(KErrNone,ETrue); + } + else + { + // DoControl + TInt rtn = DoControl(id,m.Ptr0(),aMsg); + m.Complete(rtn,ETrue); + } + DP("DWebcameraLogicalChannel::HandleMsg() end"); + } + +/** + Process synchronous 'control' requests +*/ +TInt DWebcameraLogicalChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2) + { + DP("DWebcameraLogicalChannel::DoControl() start"); + TInt rtn; + TThreadMessage& m=*(TThreadMessage*)a2; + TRequestStatus* pS=(TRequestStatus*)m.Ptr0(); + + switch (aFunction) + { + case RWebcameraDevice::EGetConfig: +// rtn = GetConfig((TDes8*)a1); + rtn = KErrNone; + if ( rtn != KErrNone ) + { + Kern::RequestComplete(iClient,pS,rtn); + } + break; + case RWebcameraDevice::ESetConfig: + // rtn = SetConfig((const TDesC8*)a1); + break; + + default: + rtn = KErrNotSupported; + Kern::RequestComplete(iClient,pS,rtn); + break; + } + DP("DWebcameraLogicalChannel::DoControl() end"); + return rtn; + + } + +/** + Process asynchronous requests. +*/ +TInt DWebcameraLogicalChannel::DoRequest(TInt aReqNo, + TRequestStatus* aStatus, + TAny* a1, + TAny* a2) + { + DP("DWebcameraLogicalChannel::DoRequest() start"); + TInt rtn; + TThreadMessage& m=*(TThreadMessage*)a2; + + iRequesting =ETrue; + rtn = KErrNone; + DP("aReqNo=%d",aReqNo); + switch(aReqNo) + { + case RWebcameraDevice::EStart: + DP("EStart=%d",RWebcameraDevice::EStart); + iReceiveDataStatus = aStatus; + iReceiving = ETrue ; + iReceiveDataBuffer->FillZ(iCaptureBuffer->MaxLength()); + iReceiveDataBuffer->Zero(); + DP("iReceiveDataBuffer Len=%d",iReceiveDataBuffer->MaxLength()); + DP("iReceiveDataBuffer Len=%d",iReceiveDataBuffer->Length()); + rtn = Pdd()->StartViewerFinder(iPhysAddr,iSize); + if ( rtn != KErrNone ) + { + DP("rtn=%d",rtn); + iReceiving = EFalse ; + Kern::RequestComplete(iClient,aStatus,rtn); + } + else + { + DP("rtn=%d",rtn); + // Example Platform Security capability check which tests the + // client for ECapability_None (which always passes)... + if ( iRequesting == EFalse ) + { + DP("iRequesting=EFalse"); + iReceiving = EFalse ; + Kern::RequestComplete(iClient, + iReceiveDataStatus, + iReceiveDataResult); + } + else + { + DP("iRequesting=ETrue"); + iReceiveDataDescriptor=(TDes8*)a1; + } + } + break; + case RWebcameraDevice::ECapture: + iCaptureing = ETrue ; + iCaptureStatus = aStatus; + iCaptureBuffer->FillZ(iCaptureBuffer->MaxLength()); + iCaptureBuffer->Zero(); + DP("iCaptureBuffer Len=%d",iCaptureBuffer->MaxLength()); + DP("iCaptureBuffer Len=%d",iCaptureBuffer->Length()); + rtn = Pdd()->StartCapture(iPhysAddr,iSize); + DP("rtn=%d",rtn); + if ( rtn != KErrNone ) + { + iCaptureing = EFalse ; + Kern::RequestComplete(iClient,aStatus,rtn); + } + else + { + if ( iRequesting == EFalse ) + { + DP("iRequesting=EFalse"); + iReceiving = EFalse ; + Kern::RequestComplete(iClient,iCaptureStatus,iCaptureResult); + } + else + { + DP("Capture iRequesting=ETrue"); + iCaptureDescriptor=(TDes8*)a1; + } + } + break; + default: + rtn=KErrNotSupported; + Kern::RequestComplete(iClient,aStatus,rtn); + break; + } + iRequesting = EFalse; + + DP("DWebcameraLogicalChannel::DoRequest() end"); + return rtn; + + } + +/** + Process cancelling of asynchronous requests. +*/ +void DWebcameraLogicalChannel::DoCancel(TUint aMask) + { + DP("DWebcameraLogicalChannel::DoCancel() start"); + TInt rtn; + DP("aMask=%d",aMask); + if (aMask&(1<Stop(DWebcameraDriverBase::USB_cancel); + iReceiving = EFalse ; + iReceiveDataDfc.Cancel(); + Kern::RequestComplete(iClient,iReceiveDataStatus,KErrCancel); + } + } + if (aMask&(1<Stop(DWebcameraDriverBase::USB_cancel); + iReceiving = EFalse ; + iCaptureDfc.Cancel(); + Kern::RequestComplete(iClient,iCaptureStatus,KErrCancel); + } + } + DP("DWebcameraLogicalChannel::DoCancel() end"); + } + +/** + Called by PDD from ISR to indicate that a ReceiveData operation has completed. +*/ +void DWebcameraLogicalChannel::GetOneFlameComplete(TInt aDataSize) + { + DP("DWebcameraLogicalChannel::GetOneFlameComplete() start"); + DP("datasize=%d",aDataSize); + iSaveSize=iSize - aDataSize; + // Queue DFC + iReceiveDataDfc.Add(); + //set size of received data + if (iSaveSize > 0) + { + iReceiveDataResult = KErrNone; + } + else + { + iReceiveDataResult = KErrUnknown;//TODO:define of error + } + DP("DWebcameraLogicalChannel::GetOneFlameComplete() end"); + } + +/** + Called by PDD from ISR to indicate that a get capture image operation has completed. +*/ +void DWebcameraLogicalChannel::CaptureComplete(TInt aDataSize) + { + DP("DWebcameraLogicalChannel::CaptureComplete() start"); + DP("datasize=%d",aDataSize); + iSaveSize=iSize - aDataSize; + // Queue DFC + iCaptureDfc.Add(); + //set size of received data + if (iSaveSize > 0) + { + iCaptureResult = KErrNone; + } + else + { + iCaptureResult = KErrUnknown;//TODO:define of error + } + DP("DWebcameraLogicalChannel::CaptureComplete() end"); + } + +/** + DFC Callback which gets triggered after the PDD has signalled that getting oneflame completed. + This just casts aPtr and calls DoGetOneFlameComplete(). +*/ +void DWebcameraLogicalChannel::GetOneFlameDfc(TAny* aPtr) + { + DP("DWebcameraLogicalChannel::GetOneFlameDfc() start"); + ((DWebcameraLogicalChannel*)aPtr)->DoGetOneFlameComplete(); + DP("DWebcameraLogicalChannel::GetOneFlameDfc() end"); + } + +/** + DFC Callback which gets triggered after the PDD has signalled that getting Capture image completed. + This just casts aPtr and calls DoCaptureComplete(). +*/ +void DWebcameraLogicalChannel::CaptureDfc(TAny* aPtr) + { + DP("DWebcameraLogicalChannel::CaptureDfc() start"); + ((DWebcameraLogicalChannel*)aPtr)->DoCaptureComplete(); + DP("DWebcameraLogicalChannel::CaptureDfc() end"); + } + +/** + Called from a DFC after the PDD has signalled that getting oneflame completed. +*/ +void DWebcameraLogicalChannel::DoGetOneFlameComplete() + { + DP("DWebcameraLogicalChannel::DoGetOneFlameComplete() start"); + iReceiveDataBuffer->Copy(iLAdr,iSaveSize); + DP("iReceiveDataBuffer Len=%d",iReceiveDataBuffer->Length()); + // Write data to client from our buffer + TInt result=Kern::ThreadDesWrite(iClient,iReceiveDataDescriptor,*iReceiveDataBuffer,0); + // Finished with client descriptor, so NULL it to help detect coding errors + iReceiveDataDescriptor = NULL; + + // Use result code from PDD if it was an error + if(iReceiveDataResult!=KErrNone) + result = iReceiveDataResult; + + // Complete clients request + Kern::RequestComplete(iClient,iReceiveDataStatus,result); + DP("DWebcameraLogicalChannel::DoGetOneFlameComplete() end"); + } + +/** + Called from a DFC after the PDD has signalled that getting Capture image completed. +*/ +void DWebcameraLogicalChannel::DoCaptureComplete() + { + DP("DWebcameraLogicalChannel::DoCaptureComplete() start"); + iCaptureBuffer->Copy(iLAdr,iSaveSize); + DP("iCaptureBuffer Len=%d",iCaptureBuffer->Length()); + // Write data to client from our buffer + TInt result=Kern::ThreadDesWrite(iClient,iCaptureDescriptor,*iCaptureBuffer,0); + // Finished with client descriptor, so NULL it to help detect coding errors + iCaptureDescriptor = NULL; + + // Use result code from PDD if it was an error + if(iCaptureResult!=KErrNone) + result = iCaptureResult; + + // Complete clients request + Kern::RequestComplete(iClient,iCaptureStatus,result); + DP("DWebcameraLogicalChannel::DoCaptureComplete() end"); + } + +/** + Process a GetConfig control message. This writes the current driver configuration to a + RWebcameraDevice::TConfigBuf supplied by the client. +*/ +TInt DWebcameraLogicalChannel::GetConfig(TDes8* aConfigBuf) + { + //unsupported + } + +/** + Process a SetConfig control message. This sets the driver configuration using a + RWebcameraDevice::TConfigBuf supplied by the client. +*/ +TInt DWebcameraLogicalChannel::SetConfig(const TDesC8* aConfigBuf) + { + //unsupported + } + +/** + Fill a TConfig with the drivers current configuration. +*/ +/*void DWebcameraLogicalChannel::CurrentConfig(RWebcameraDevice::TConfig& aConfig) + { + //unsupported + } +*/ + +/** + *Get the point to Physical channel. + */ +DWebcameraDriverBase* DWebcameraLogicalChannel::Pdd() + { + DP("DWebcameraLogicalChannel::Pdd() start"); + return (DWebcameraDriverBase*)iPdd; + } + diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/webcamera/webcamera_ldd.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/webcamera/webcamera_ldd.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,242 @@ +/* +* Copyright (c) 2010 ISB. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* ISB - initial contribution. +* +* Contributors: +* +* Description: USB driver for test +* +*/ +#ifndef __deviceLDD_H__ +#define __deviceLDD_H__ + +#include +#include "webcamera_device.h" + +#define BUFSIZE (100*1024) +/** + *Logical channel class + * + */ +class DWebcameraLogicalDevice : public DLogicalDevice + { +public: + DWebcameraLogicalDevice(); + ~DWebcameraLogicalDevice(); + /** + Second stage constructor for DDriver1Factory. + This must at least set a name for the driver object. + + @return KErrNone if successful, otherwise one of the other system wide error codes. + */ + virtual TInt Install(); + /** + Return the drivers capabilities. + Called in the response to an RDevice::GetCaps() request. + + @param aDes User-side descriptor to write capabilities information into + */ + virtual void GetCaps(TDes8& aDes) const; + /** + Called by the kernel's device driver framework to create a Logical Channel. + This is called in the context of the user thread (client) which requested the creation of a Logical Channel + (E.g. through a call to RBusLogicalChannel::DoCreate) + The thread is in a critical section. + + @param aChannel Set to point to the created Logical Channel + + @return KErrNone if successful, otherwise one of the other system wide error codes. + */ + virtual TInt Create(DLogicalChannelBase*& aChannel); + }; + +/** + * + * ˜_—ƒ`ƒƒƒlƒ‹ƒx[ƒXƒNƒ‰ƒX + * + * –{ƒNƒ‰ƒX‚ÍA˜_—ƒ`ƒƒƒlƒ‹‹@”\‚ð’ñ‹Ÿ‚·‚éB + * + * @ + * @ + * + */ +class DWebcameraLogicalChannel : public DWebcameraLogicalChannelBase + { +public: + /** + Constructor + */ + DWebcameraLogicalChannel(); + /** + Destructor + */ + ~DWebcameraLogicalChannel(); + /** + Called when a user thread requests a handle to this channel. + */ + virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType); + /** + Second stage constructor called by the kernel's device driver framework. + This is called in the context of the user thread (client) which requested the creation of a Logical Channel + The thread is in a critical section. + + @param aUnit The unit argument supplied by the client + @param aInfo The info argument supplied by the client + @param aVer The version argument supplied by the client + + @return KErrNone if successful, otherwise one of the other system wide error codes. + */ + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); + /** + Process a message for this logical channel. + This function is called in the context of a DFC thread. + + @param aMessage The message to process. + The iValue member of this distinguishes the message type: + iValue==ECloseMsg, channel close message + iValue==KMaxTInt, a 'DoCancel' message + iValue>=0, a 'DoControl' message with function number equal to iValue + iValue<0, a 'DoRequest' message with function number equal to ~iValue + */ + virtual void HandleMsg(TMessageBase* aMsg); + /** + Process synchronous 'control' requests + */ + virtual TInt DoControl(TInt aFunction, TAny* a1, TAny* a2); + /** + Process asynchronous requests. + */ + virtual TInt DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2); + /** + Process cancelling of asynchronous requests. + */ + virtual void DoCancel(TUint aMask); + /** + Called by PDD from ISR to indicate that a get oneflame operation has completed. + */ + virtual void GetOneFlameComplete(TInt aResult); + /** + Called by PDD from ISR to indicate that a get capture image operation has completed. + */ + virtual void CaptureComplete(TInt aResult); + /** + DFC Callback which gets triggered after the PDD has signalled that get oneflame completed. + This just casts aPtr and calls DoGetOneFlameComplete(). + */ + static void GetOneFlameDfc(TAny* aPtr); + /** + DFC Callback which gets triggered after the PDD has signalled that getting Capture image completed. + This just casts aPtr and calls DoCaptureComplete(). + */ + static void CaptureDfc(TAny* aPtr); + /** + Called from a DFC after the PDD has signalled that getting oneflame completed. + */ + virtual void DoGetOneFlameComplete(); + /** + Called from a DFC after the PDD has signalled that getting Capture image completed. + */ + virtual void DoCaptureComplete(); + + /** + Process a GetConfig control message. This writes the current driver configuration to a + RWebcameraDevice::TConfigBuf supplied by the client. + */ + TInt GetConfig(TDes8* aConfigBuf); + /** + Process a SetConfig control message. This sets the driver configuration using a + RWebcameraDevice::TConfigBuf supplied by the client. + */ + TInt SetConfig(const TDesC8* aConfigBuf); +// void CurrentConfig(RWebcameraDevice::TConfig& aConfig); + /** + *Get the point to Physical channel. + */ + DWebcameraDriverBase* Pdd(); + +private: + /** + *point to description sent by user-side. + */ + TDes8* iReceiveDataDescriptor; + /** + *buffer for one flame. + */ + HBuf8* iReceiveDataBuffer; + /** + *the status getting one flame. + */ + TRequestStatus* iReceiveDataStatus; + /** + *DFC for getting one flame. + */ + TDfc iReceiveDataDfc; + /** + *the result of the get oneflame operation. + */ + TInt iReceiveDataResult; + /** + */ + TBool iReceiving; + /** + *point to description sent by user-side. + */ + TDes8* iCaptureDescriptor; + /** + *buffer for capture image. + */ + HBuf8* iCaptureBuffer; + /** + *the status getting capture image. + */ + TRequestStatus* iCaptureStatus; + /** + *DFC of capture. + */ + TDfc iCaptureDfc; + /** + *the result of the capture operation. + */ + TInt iCaptureResult; + /** + *the status getting capture image. + */ + TBool iCaptureing; + /** + *the status of request. + */ + TBool iRequesting; + /** + *point to memory used to save one frame or capture image. + */ + HBuf8* iComm; + /** + *Physical adress of contiguous memory. + */ + TUint32 iPhysAddr; + /** + *the size of buffer used to save one frame or capture image. + */ + TInt iSize; + /** + *chunck. + */ + DPlatChunkHw* iChunk; + /** + *Linear adress of chunck. + */ + TUint8* iLAdr; + /** + *the size of received data. + */ + TInt iSaveSize; + }; + +#endif diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/webcamera/webcamera_ldd.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/webcamera/webcamera_ldd.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2010 ISB. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* ISB - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include +#include "kernel/kern_ext.mmh" + +TARGET VariantTarget(ewebcamera,ldd) +linkas ewebcamera.ldd +TARGETTYPE ldd + +SYSTEMINCLUDE /epoc32/include/drivers +SYSTEMINCLUDE /epoc32/include/platform/drivers +SYSTEMINCLUDE AsspNKernIncludePath + +SOURCEPATH . +SOURCE webcamera_ldd.cpp + +LIBRARY PlatformLib + +EPOCALLOWDLLDATA + +UID 0x100000af 0x1020044C //TODO:C³‚·‚é•K—v +//VENDORID 0x70000001 + +//ROMTARGET ewebcamera.ldd + +CAPABILITY all diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/webcamera/webcamera_pdd.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/webcamera/webcamera_pdd.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,186 @@ +/* +* Copyright (c) 2010 ISB. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* ISB - initial contribution. +* +* Contributors: +* +* Description: USB driver for test +* +*/ + +#include "webcamera_pdd.h" +#include + +#define DP(format...) Kern::Printf(format) + +//Name for PDD +_LIT(KWebcameraPddName,"WebcameraDevice.pdd"); + +// --------------------------------------------------------------- +// --------------------------------------------------------------- + +DWebcameraPddFactory::DWebcameraPddFactory() +{ + DP("DWebcameraPddFactory::DWebcameraPddFactory()"); + iVersion=TVersion(KCommsMajorVersionNumber,KCommsMinorVersionNumber,KCommsBuildVersionNumber); +} + +TInt DWebcameraPddFactory::Install() +{ + DP("DWebcameraPddFactory::Install"); + return SetName(&KWebcameraPddName); +} + +void DWebcameraPddFactory::GetCaps(TDes8 &aDes) const +{ + DP("DWebcameraPddFactory::GetCaps start"); + RWebcameraDevice::TCaps capsBuf; + capsBuf.iVersion = iVersion; + aDes.FillZ(aDes.MaxLength()); + TInt size=sizeof(capsBuf); + if(size>aDes.MaxLength()) + { + size=aDes.MaxLength(); + } + aDes.Copy((TUint8*)&capsBuf,size); + DP("DWebcameraPddFactory::GetCaps end"); +} + +TInt DWebcameraPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer) +{ + DP("DWebcameraPddFactory::Create start"); + DWebcameraDriver* pD=new DWebcameraDriver; + aChannel=pD; + TInt r=KErrNoMemory; + if (pD) + { + r=pD->DoCreate(aUnit,anInfo); + } + DP("DWebcameraPddFactory::Create end"); + return r; +} + +TInt DWebcameraPddFactory::Validate(TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& aVer) +{ + DP("DWebcameraPddFactory::Validate start"); + if ((!Kern::QueryVersionSupported(iVersion,aVer)) || + (!Kern::QueryVersionSupported(aVer,TVersion(KMinimumLddMajorVersion,KMinimumLddMinorVersion,KMinimumLddBuild)))) + { + return KErrNotSupported; + } + DP("DWebcameraPddFactory::Validate end"); + return KErrNone; +} + +// --------------------------------------------------------------- +// --------------------------------------------------------------- + +DWebcameraDriver::DWebcameraDriver() +{ + DP("DWebcameraDriver::DWebcameraDriver start"); + DP("DWebcameraDriver::DWebcameraDriver end"); +} + +DWebcameraDriver::~DWebcameraDriver() +{ + DP("DWebcameraDriver::~DWebcameraDriver start"); + Interrupt::Unbind(iIrq); + DP("DWebcameraDriver::~DWebcameraDriver end"); +} + +TInt DWebcameraDriver::DoCreate(TInt aUnit, const TDesC8* anInfo) +{ + DP("DWebcameraDriver::DoCreate start"); + iPortAddr=KHwSVPWebcameraDevice; + iIrq = EIrqWebamera; + Interrupt::Bind(iIrq,Isr,this); + DP("DWebcameraDriver::DoCreate end"); + return KErrNone; +} + +TInt DWebcameraDriver::StartViewerFinder(TUint aBuffer,TInt aSize) +{ + DP("DWebcameraDriver::StartViewerFinder start"); + iType=0; + TUint32 temp=(TUint32)aBuffer; + DP("temp=%x",temp); + DP("iPortAddr=%x",iPortAddr); + WriteReg(iPortAddr,WEBCAMERA_REG_DATA_TYPE, 0x0); + WriteReg(iPortAddr,WEBCAMERA_REG_DMA_ADDR,temp); + WriteReg(iPortAddr,WEBCAMERA_REG_DMA_SIZE, aSize); + WriteReg(iPortAddr,WEBCAMERA_REG_INT_ENABLE, 0x1); + Interrupt::Enable(iIrq); + + DP("DWebcameraDriver::StartViewerFinder END"); + return KErrNone; +} + +TInt DWebcameraDriver::StartCapture(TUint aBuffer,TInt aSize) +{ + DP("DWebcameraDriver::StartCapture start"); + // Save a pointer to the buffer we need to put the 'recevied' data in + iType=1; + TUint32 temp=(TUint32)aBuffer; + DP("temp=%x",temp); + WriteReg(iPortAddr,WEBCAMERA_REG_DATA_TYPE, 0x1); + WriteReg(iPortAddr,WEBCAMERA_REG_DMA_ADDR,temp); + WriteReg(iPortAddr,WEBCAMERA_REG_DMA_SIZE, aSize); + WriteReg(iPortAddr,WEBCAMERA_REG_INT_ENABLE, 0x1); + Interrupt::Enable(iIrq); + + DP("DWebcameraDriver::StartCapture END"); + return KErrNone; +} + +void DWebcameraDriver::Stop(TUSBStopMode aMode) +{ + DP("DWebcameraDriver::Stop start"); + WriteReg(iPortAddr, WEBCAMERA_REG_INT_ENABLE, 0x0); + Interrupt::Disable(iIrq); + DP("DWebcameraDriver::Stop end"); +} + +void DWebcameraDriver::Isr(TAny* aPtr) +{ + DP("DWebcameraDriver::Isr start"); + ((DWebcameraDriver*)aPtr)->receivedatacallback(); + DP("DWebcameraDriver::Isr end"); +} + +void DWebcameraDriver::receivedatacallback() +{ + DP("DWebcameraDriver::receivedatacallback start"); + TInt datasize=ReadReg(iPortAddr,WEBCAMERA_REG_DMA_SIZE); + switch (iType) + { + case 0: + iLdd->GetOneFlameComplete(datasize); + break; + case 1: + iLdd->CaptureComplete(datasize); + break; + default: + // + } + WriteReg(iPortAddr,WEBCAMERA_REG_DMA_ADDR, 0); + WriteReg(iPortAddr,WEBCAMERA_REG_DMA_SIZE, 0); + WriteReg(iPortAddr,WEBCAMERA_REG_INT_ENABLE, 0x0); + DP("DWebcameraDriver::receivedatacallback end"); +} + +// --------------------------------------------------------------- +// --------------------------------------------------------------- + +DECLARE_STANDARD_PDD() +{ + DP("DECLARE_STANDARD_PDD()"); + return new DWebcameraPddFactory; +} + diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/webcamera/webcamera_pdd.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/webcamera/webcamera_pdd.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,120 @@ +/* +* Copyright (c) 2010 ISB. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* ISB - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#ifndef __devicePDD_H__ +#define __devicePDD_H__ + +#include +#include +#include "system.h" +#include "webcamera_device.h" + +const TInt KMinimumLddMajorVersion=1; +const TInt KMinimumLddMinorVersion=1; +const TInt KMinimumLddBuild=0; +const TInt EIrqWebamera=0xb; + +class DWebcameraPddFactory : public DPhysicalDevice +{ +public: + /** + Constructor + */ + DWebcameraPddFactory(); + + virtual TInt Install(); + virtual void GetCaps(TDes8 &aDes) const; + virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion &aVer); + virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer); +}; + + +class DWebcameraDriver : public DWebcameraDriverBase +{ +public: + /** + Constructor + */ + DWebcameraDriver(); + /** + Destructor + */ + ~DWebcameraDriver(); + /** + Second stage constructor called by the kernel's device driver framework. + This is called in the context of the user thread (client) which requested the creation of a Logical Channel + The thread is in a critical section. + + @param aUnit The unit argument supplied by the client + @param aInfo The info argument supplied by the client + + @return KErrNone if successful, otherwise one of the other system wide error codes. + */ + TInt DoCreate(TInt aUnit, const TDesC8* anInfo); + /** + Request data from device. + Only one send request may be pending at any time. + + @param aBuffer physical adress + @param aData size of buffer. + */ + virtual TInt StartViewerFinder(TUint aBuffer,TInt aSize); + /** + Request data from device. + Only one send request may be pending at any time. + + @param aBuffer physical adress + @param aData size of buffer. + */ + virtual TInt StartCapture(TUint aBuffer,TInt aSize); + /** + Request device not to send data. + Only one send request may be pending at any time. + + @param aMode stop mode + */ + virtual void Stop(TUSBStopMode aMode); +// virtual void Caps(TDes8 &aCaps) const; + /** + Called by ISR to indicate that interrupt occurs. + */ + static void Isr(TAny* aPtr); + /** + Called from a Isr after the Peripheral has signalled that getting oneflame completed. + */ + void receivedatacallback(); + +public: + /** + Enumeration of register types. + */ + enum { + WEBCAMERA_REG_ID = 0, + WEBCAMERA_REG_INT_ENABLE = 1, + WEBCAMERA_REG_DATA_TYPE = 2, + WEBCAMERA_REG_DMA_ADDR = 3, + WEBCAMERA_REG_DMA_SIZE = 4 + }; + +private: + /** + operation types. + */ + TInt iType; +}; + +#endif diff -r 2c1e559d48bf -r f24810eebc6b baseport/syborg/webcamera/webcamera_pdd.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/webcamera/webcamera_pdd.mmp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2010 ISB. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* ISB - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include +#include "kernel/kern_ext.mmh" + +TARGET VariantTarget(webcamera,pdd) +linkas webcamera.pdd +TARGETTYPE pdd + +SYSTEMINCLUDE /epoc32/include/drivers +SYSTEMINCLUDE /epoc32/include/platform/drivers +SYSTEMINCLUDE AsspNKernIncludePath + +SOURCEPATH . +SOURCE webcamera_pdd.cpp + +LIBRARY PlatformLib + +EPOCALLOWDLLDATA + +UID 0x100039d0 0x1020044D //TODO:C³‚·‚é•K—v +//VENDORID 0x70000001 + +//ROMTARGET webcamera.pdd + +CAPABILITY all diff -r 2c1e559d48bf -r f24810eebc6b docs/wiki/ELF4ROM.doc Binary file docs/wiki/ELF4ROM.doc has changed diff -r 2c1e559d48bf -r f24810eebc6b docs/wiki/SVP E32-F32 Testing.doc Binary file docs/wiki/SVP E32-F32 Testing.doc has changed diff -r 2c1e559d48bf -r f24810eebc6b symbian-qemu-0.9.1-12/qemu-symbian-svp/devtree.c --- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/devtree.c Tue Apr 06 16:31:41 2010 +0100 +++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/devtree.c Tue Apr 06 17:00:22 2010 +0100 @@ -26,6 +26,7 @@ #include "devtree.h" #include "hw/boards.h" #include "libfdt/libfdt.h" +#include "qemu-char.h" #define BADF(fmt, args...) \ do { fprintf(stderr, "error: " fmt , ##args); exit(1);} while (0) @@ -413,7 +414,15 @@ if (propstr) { i = sscanf(propstr, "serial%d", &n); if (i == 1 && n >= 0 && n < MAX_SERIAL_PORTS) + { + if (!serial_hds[n]) + { + const char* target = fdt_getprop_string(dt, node, "target"); + if (target) + serial_hds[n] = qemu_chr_open(propstr, target); + } d->chardev = serial_hds[n]; + } } } find_properties(d); diff -r 2c1e559d48bf -r f24810eebc6b symbian-qemu-0.9.1-12/qemu-symbian-svp/plugins/qemu_arm_plugins.py --- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/plugins/qemu_arm_plugins.py Tue Apr 06 16:31:41 2010 +0100 +++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/plugins/qemu_arm_plugins.py Tue Apr 06 17:00:22 2010 +0100 @@ -5,3 +5,4 @@ import syborg_timer import syborg_keyboard import syborg_pointer +import syborg_usbtest diff -r 2c1e559d48bf -r f24810eebc6b symbian-qemu-0.9.1-12/qemu-symbian-svp/plugins/syborg_serial.py --- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/plugins/syborg_serial.py Tue Apr 06 16:31:41 2010 +0100 +++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/plugins/syborg_serial.py Tue Apr 06 17:00:22 2010 +0100 @@ -1,4 +1,6 @@ import qemu +import os +import sys class syborg_serial(qemu.devclass): REG_ID = 0 @@ -127,6 +129,57 @@ regions = [qemu.ioregion(0x1000, readl=read_reg, writel=write_reg)] irqs = 1 name = "syborg,serial" - properties = {"fifo-size":16, "chardev":None} + properties = {"fifo-size":16, "chardev":None, "target": ""} qemu.register_device(syborg_serial) + +class syborg_modem(syborg_serial): + + def create(self): + syborg_serial.create(self) + + # Find the path of the emulator executable + path = os.path.dirname(sys.executable) + executable = os.getenv("SVP_MODEM_EXECUTABLE") + if None == executable: + executable = self.modem_executable + + executable_name = executable + fq_executable = os.path.join(path, executable_name) + print(fq_executable) + + if not os.path.exists(fq_executable): + executable_name = executable + ".exe" + fq_executable = os.path.join(path, executable_name) + + if not os.path.exists(fq_executable): + sys.exit("Could not locate modem executable '" + executable + "' in '" + path + "'!\n") + + # Attempt to find the correct port from the target spec + target = self.properties["target"] + + if not(target.startswith("tcp:") or target.startswith("udp:")): + sys.exit("Modem device is not accessed via an acceptable socket.") + + target = target[4:] + port_start_idx = target.find(":"); + port_end_idx = target.find(",") + if -1 == port_start_idx: + sys.exit("Could not extract port number from modem target spec!") + + port = "" + if -1 == port_end_idx: + port = target[port_start_idx + 1:] + else: + port = target[port_start_idx + 1:port_end_idx] + + os.spawnl(os.P_NOWAIT, fq_executable, executable_name, "-p", port) + self.chardev.handle_connect() + + # Name property override. + name = "syborg,serial,modem" + + # Default modem executable + modem_executable = "phonesim" + +qemu.register_device(syborg_modem) diff -r 2c1e559d48bf -r f24810eebc6b symbian-qemu-0.9.1-12/qemu-symbian-svp/plugins/syborg_usbtest.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/plugins/syborg_usbtest.py Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,113 @@ +import qemu +import os + +class syborg_usbtest(qemu.devclass): + REG_ID = 0 + REG_INT_ENABLE = 1 + REG_DATA_TYPE = 2 + REG_DMA_ADDR = 3 + REG_DMA_SIZE = 4 + + def loadIMG(self): + self.buf = open('test1.BMP','rb').read() + self.bufC = open('test.BMP','rb').read() + self.bmpsize = os.path.getsize('test1.BMP') + self.Csize = os.path.getsize('test.BMP') + + def timertick(self): + if self.cha==0: + compSize=self.bmpsize + buf=self.buf + self.cha=1 + else: + compSize=self.Csize + buf=self.bufC + self.cha=0 + if self.dma_size < compSize: + self.dma_size = 0 + else: + for x in buf: + ch = ord(x) + if self.dma_size > 0: + self.dma_writeb(self.dma_addr, ch) + self.dma_addr += 1 + self.dma_size -= 1 + self.set_irq_level(0, self.int_enable) + + def timer_on(self): + self.ptimer = qemu.ptimer(self.timertick, 1) + self.ptimer.run(0) + + def timer_off(self): + self.ptimer.stop() + self.set_irq_level(0, self.int_enable) + + def capturedata(self): + if self.dma_size < self.Csize: + self.dma_size = 0 + else: + for x in self.bufC: + ch = ord(x) + if self.dma_size > 0: + self.dma_writeb(self.dma_addr, ch) + self.dma_addr += 1 + self.dma_size -= 1 + self.set_irq_level(0, self.int_enable) + + def create(self): + self.int_enable = 1 + self.dma_addr = 0 + self.dma_size =0 + self.cha=0 + self.loadIMG() + + def write_reg(self, offset, value): + offset >>= 2 + if offset==self.REG_INT_ENABLE: + self.int_enable=value + if value==1: + if self.data_type==0: + self.timer_on() + elif self.data_type==1: + self.capturedata() + else: + if self.data_type==0: + self.timer_off() + elif self.data_type==1: + self.set_irq_level(0, self.int_enable) + elif offset == self.REG_DATA_TYPE: + self.data_type = value + elif offset == self.REG_DMA_ADDR: + self.dma_addr = value + elif offset == self.REG_DMA_SIZE: + self.dma_size = value + + def read_reg(self, offset): + offset >>= 2 + if offset == self.REG_ID: + return 0xc600f000 + elif offset == self.REG_INT_ENABLE: + return self.int_enable + elif offset == self.REG_DMA_ADDR: + return self.dma_addr + elif offset == self.REG_DMA_SIZE: + return self.dma_size + return 0 + + def save(self, f): + f.put_u32(self.int_enable) + f.put_u32(self.dma_addr) + f.put_u32(self.dma_size) + + def load(self, f): + self.int_enable = f.get_u32() + self.dma_addr = f.get_u32() + self.dma_size = f.get_u32() + + # Device class properties + regions = [qemu.ioregion(0x1000, readl=read_reg, writel=write_reg)] + irqs = 1 + name = "syborg,usbtest" + properties={"chardev":None} + +qemu.register_device(syborg_usbtest) diff -r 2c1e559d48bf -r f24810eebc6b symbian-qemu-0.9.1-12/qemu-symbian-svp/python-plugin.c --- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/python-plugin.c Tue Apr 06 16:31:41 2010 +0100 +++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/python-plugin.c Tue Apr 06 17:00:22 2010 +0100 @@ -1072,6 +1072,17 @@ return 0; } +static PyObject *qemu_py_chardev_handle_connect(qemu_py_chardev *self, + PyObject *args) +{ + if (!self->chr) + Py_RETURN_NONE; + + qemu_chr_connect(self->chr); + + Py_RETURN_NONE; +} + static PyObject *qemu_py_chardev_set_handlers(qemu_py_chardev *self, PyObject *args, PyObject *kwds) { @@ -1147,6 +1158,9 @@ }; static PyMethodDef qemu_py_chardev_methods[] = { + {"handle_connect", (PyCFunction)qemu_py_chardev_handle_connect, + METH_NOARGS, + "Handle character device connect if required"}, {"set_handlers", (PyCFunction)qemu_py_chardev_set_handlers, METH_VARARGS|METH_KEYWORDS, "Set event handlers"}, diff -r 2c1e559d48bf -r f24810eebc6b symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.c --- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.c Tue Apr 06 16:31:41 2010 +0100 +++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.c Tue Apr 06 17:00:22 2010 +0100 @@ -123,6 +123,12 @@ } } +void qemu_chr_connect(CharDriverState *s) +{ + if (s->chr_connect) + s->chr_connect(s); +} + int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len) { return s->chr_write(s, buf, len); @@ -605,6 +611,20 @@ return qemu_chr_open_fd(-1, fd_out); } +static CharDriverState *qemu_chr_open_tempfile_out(const char *temp_file) +{ + CharDriverState *ret = NULL; + const char *temp_format = "/tmp/%s"; + char *fname = qemu_mallocz(sizeof(char) * (strlen(temp_path) + strlen(temp_file))); + if (fname) + { + sprintf(fname, temp_format, temp_file); + ret = qemu_chr_open_file_out(fname); + qemu_free(fname); + } + return ret; +} + static CharDriverState *qemu_chr_open_pipe(const char *filename) { int fd_in, fd_out; @@ -1757,6 +1777,29 @@ return qemu_chr_open_win_file(fd_out); } + +static CharDriverState *qemu_chr_open_win_tempfile_out(const char *temp_file) +{ + CharDriverState *ret = NULL; + char* fname; + const char* temp_format = "%s\\%s"; + const char* temp_path; + + temp_path = getenv("TEMP"); + if (temp_path) + { + fname = qemu_mallocz(sizeof(char) * (strlen(temp_path) + strlen(temp_file) + strlen(temp_format))); + if (fname) + { + sprintf(fname, temp_format, temp_path, temp_file); + ret = qemu_chr_open_win_file_out(fname); + qemu_free(fname); + } + } + + return ret; +} + #endif /* !_WIN32 */ /***********************************************************/ @@ -1886,6 +1929,8 @@ int do_telnetopt; int do_nodelay; int is_unix; + int wait_connect; + int device_handles_connect; } TCPCharDriver; static void tcp_chr_accept(void *opaque); @@ -2063,6 +2108,26 @@ tcp_chr_connect(chr); } +static void tcp_chr_do_connect(CharDriverState* chr) +{ + TCPCharDriver *driver = (TCPCharDriver*)chr->opaque; + if (driver->device_handles_connect) + { + if (-1 != driver->listen_fd) + { + printf("QEMU waiting for connection...\n"); + tcp_chr_accept(chr); + socket_set_nonblock(driver->listen_fd); + } + else + { + driver->connected = 1; + socket_set_nodelay(driver->fd); + tcp_chr_connect(chr); + } + } +} + static void tcp_chr_close(CharDriverState *chr) { TCPCharDriver *s = chr->opaque; @@ -2083,6 +2148,7 @@ int is_listen = 0; int is_waitconnect = 1; int do_nodelay = 0; + int is_device_handles_connect = 0; const char *ptr; ptr = host_str; @@ -2096,6 +2162,8 @@ do_nodelay = 1; } else if (!strncmp(ptr,"to=",3)) { /* nothing, inet_listen() parses this one */; + } else if (!strncmp(ptr, "devicehandlesconnect", 20) && !is_unix) { + is_device_handles_connect = 1; } else { printf("Unknown option: %s\n", ptr); goto fail; @@ -2107,6 +2175,7 @@ chr = qemu_mallocz(sizeof(CharDriverState)); if (!chr) goto fail; + s = qemu_mallocz(sizeof(TCPCharDriver)); if (!s) goto fail; @@ -2147,10 +2216,13 @@ s->listen_fd = -1; s->is_unix = is_unix; s->do_nodelay = do_nodelay && !is_unix; + s->wait_connect = is_waitconnect; + s->device_handles_connect = is_device_handles_connect; chr->opaque = s; chr->chr_write = tcp_chr_write; chr->chr_close = tcp_chr_close; + chr->chr_connect = tcp_chr_do_connect; if (is_listen) { s->listen_fd = fd; @@ -2158,13 +2230,17 @@ if (is_telnet) s->do_telnetopt = 1; } else { - s->connected = 1; s->fd = fd; - socket_set_nodelay(fd); - tcp_chr_connect(chr); + + if (!is_device_handles_connect) + { + s->connected = 1; + socket_set_nodelay(fd); + tcp_chr_connect(chr); + } } - if (is_listen && is_waitconnect) { + if (is_listen && is_waitconnect && !is_device_handles_connect) { printf("QEMU waiting for connection on: %s\n", chr->filename ? chr->filename : host_str); tcp_chr_accept(chr); @@ -2220,6 +2296,8 @@ chr = qemu_chr_open_tcp(p, 0, 1); } else if (strstart(filename, "file:", &p)) { chr = qemu_chr_open_file_out(p); + } else if (strstart(filename, "tempfile:", &p)) { + chr = qemu_chr_open_tempfile_out(p); } else if (strstart(filename, "pipe:", &p)) { chr = qemu_chr_open_pipe(p); } else if (!strcmp(filename, "pty")) { @@ -2252,6 +2330,9 @@ if (strstart(filename, "file:", &p)) { chr = qemu_chr_open_win_file_out(p); } else + if (strstart(filename, "tempfile:", &p)) { + chr = qemu_chr_open_win_tempfile_out(p); + } else if (strstart(filename, "stdio", &p)) { return qemu_chr_open_win_stdio(filename); } else diff -r 2c1e559d48bf -r f24810eebc6b symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.h --- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.h Tue Apr 06 16:31:41 2010 +0100 +++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.h Tue Apr 06 17:00:22 2010 +0100 @@ -46,6 +46,7 @@ int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len); void (*chr_update_read_handler)(struct CharDriverState *s); int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg); + void (*chr_connect)(struct CharDriverState *s); IOEventHandler *chr_event; IOCanRWHandler *chr_can_read; IOReadHandler *chr_read; @@ -64,6 +65,7 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename); void qemu_chr_close(CharDriverState *chr); void qemu_chr_printf(CharDriverState *s, const char *fmt, ...); +void qemu_chr_connect(CharDriverState *s); int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len); void qemu_chr_send_event(CharDriverState *s, int event); void qemu_chr_add_handlers(CharDriverState *s, diff -r 2c1e559d48bf -r f24810eebc6b symbian-qemu-0.9.1-12/qemu-symbian-svp/vl.c --- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/vl.c Tue Apr 06 16:31:41 2010 +0100 +++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/vl.c Tue Apr 06 17:00:22 2010 +0100 @@ -4666,14 +4666,12 @@ cyls = heads = secs = 0; translation = BIOS_ATA_TRANSLATION_AUTO; monitor_device = "vc"; - - serial_devices[0] = "vc:80Cx24C"; - for(i = 1; i < MAX_SERIAL_PORTS; i++) + + for(i = 0; i < MAX_SERIAL_PORTS; i++) serial_devices[i] = NULL; serial_device_index = 0; - - parallel_devices[0] = "vc:640x480"; - for(i = 1; i < MAX_PARALLEL_PORTS; i++) + + for(i = 0; i < MAX_PARALLEL_PORTS; i++) parallel_devices[i] = NULL; parallel_device_index = 0; diff -r 2c1e559d48bf -r f24810eebc6b tools/e32test-driver/COPYING --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/e32test-driver/COPYING Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + 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, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public 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. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff -r 2c1e559d48bf -r f24810eebc6b tools/e32test-driver/COPYING.LESSER --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/e32test-driver/COPYING.LESSER Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public 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. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff -r 2c1e559d48bf -r f24810eebc6b tools/e32test-driver/qemuruntest.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/e32test-driver/qemuruntest.py Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,199 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . + +# Launch QEMU for SVP with a specified ROM image and core using a COM port for IO +# Uses Python's Popen class for process control. +# Test output is captured by invoking QEMU in -nographic mode. This redirects serial output to stdout which can then be PIPE'd +# using Popen. +# Tests which hang(or crash into the the crash debugger) are detected using a trivial 'watchdog'. IWBN to use e.g. 'select' +# with a timeout, but this won't work on Windoze, which only supports timeout's on sockets. If the watchdog timeouts out QEMU is killed. +# When the test suite runs to (recognizable) completion QEMU is killed. Unfortunately this appears to require an OS specific +# solution. NB unrecognized completion will result in the watchdog killing QEMU. +# QemuTestRunner collects output into LineTimeInfo objects. These record the time at which each line was received. The time can be used as a crude +# measure of how long a test took to execute. +# The raw data gathered from running the tests can be retrieved using GetResults. This returns a list of LineTimeInfo objects. + +import sys +mswindows = (sys.platform == "win32") + +# import the following so we can kill QEMU + +if mswindows: +# import win32api + import signal +else: + import signal + +import os + +import time + +import re + +import subprocess +from subprocess import * + +from stat import * + +import watchdog + +__all__ = ["QemuTestRunner"] + +class LineTimeInfo(object): + def __init__(self, line, atime): + self.line = line + self.time = atime + + def GetLine(self): + return self.line + + def GetTime(self): + return self.time + +class QemuTestRunner(object): + def __init__(self, qemupath, cpu, rompath, board = 'syborg', endOfTestFn=None, displayp=False, dataFile = None): + """Create new QemuTestRunner instance.""" + self.qemupath = qemupath + self.board = board + self.cpu = cpu + self.rompath = rompath + self.endOfTestFn = endOfTestFn + self.displayp = displayp + #self.cmd = qemupath + " -M syborg -cpu " + cpu + " -kernel " + rompath + " -nographic" + self.cmd = "%s -M %s -cpu %s -kernel %s -nographic" % (qemupath, board, cpu, rompath) + self.endOfTestPattern = re.compile('RUNTESTS: Completed test script') + self.lineTimeInfo = [] + self.id = None + self.dataFile = dataFile + self.watchdog = watchdog.WatchDog(900, lambda : self.KillSim()) + + def Run(self): + self.lineTimeInfo = [] + output = False + self.timeStarted = time.gmtime() + self.id = time.strftime("%d-%m%--%Y-%H-%M-%S", self.timeStarted) + if self.dataFile != None: + filename = self.dataFile + "-" + self.GetRunId() + "-data.txt" + self.dataFileName = filename + output = open(filename, 'wb') + p = Popen( self.cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE ) + self.popen = p + stdin = p.stdin + stdout = p.stdout + stop = False + + if self.displayp: + print >> sys.stdout, self.cmd + + self.watchdog.Start() + try: + while p.poll() == None and not stop: + line = stdout.readline() + atime = time.clock() + self.watchdog.Reset() + if self.displayp and p.returncode == None: + print >> sys.stdout , line + if output and p.returncode == None: + print >> output , line + if p.returncode == None: + self.lineTimeInfo.append(LineTimeInfo(line, atime)) + if self.endOfTestFn != None: + stop = self.endOfTestFn(line) + else: + stop = self.EndOfTestp(line) + finally: + self.timeEnded = time.gmtime() + self.watchdog.Stop() + if output: + output.close() + self.testSuiteFinished = stop; + + if p.returncode == None: + self.KillSim() + return True + else: + return False + + def GetDataFileName(self): + return self.dataFileName + + def TestSuiteFinishedp(self): + return self.testSuiteFinished + + def EndOfTestp(self, l): + return re.match(self.endOfTestPattern,l) != None + + def KillSim(self): +# if mswindows: +# win32api.TerminateProcess(int(self.popen._handle), -1) +# else: + os.kill(slef.popen.pid, signal.SIGKILL) + + def GetResults(self): + return self.lineTimeInfo + + def GetRomName(self): + return self.rompath + + def GetRunId(self): + return self.id + + def GetSummary(self): + simStat = os.stat(self.qemupath) + simSummary = "QEMU Executable: %s size: %d creation time: %d\n" % (self.qemupath, simStat[ST_SIZE], simStat[ST_CTIME]) + boardSummary ="Board: %s\n" % self.board + cpuSummary = "CPU: %s\n" % self.cpu + romStat = os.stat(self.rompath) + romSummary = "ROM image: %s size: %d creation date: %d\n" % (self.rompath, romStat[ST_SIZE], romStat[ST_CTIME]) + timeFormat = "%d-%m%--%Y %H:%M:%S" + startTime = "Start time: " + time.strftime(timeFormat, self.timeStarted) + "\n" + endTime = "End time: " + time.strftime(timeFormat, self.timeEnded) + "\n" + status = "Testsuite did not complete\n" + if self.TestSuiteFinishedp(): + status = "Testsuite completed\n" + return simSummary + boardSummary + cpuSummary + romSummary + startTime + endTime + status + + def GetReportFileName(self): + return self.GetRomName() + "-" + self.GetRunId() + "-results-summary.txt" + +class PseudoRunner(QemuTestRunner): + def __init__(self, input): + #self.qemupath = qemupath + #self.board = board + #self.cpu = cpu + #self.rompath = rompath + #self.endOfTestFn = endOfTestFn + #self.displayp = displayp + #self.cmd = qemupath + " -M syborg -cpu " + cpu + " -kernel " + rompath + " -nographic" + #self.endOfTestPattern = re.compile('RUNTESTS: Completed test script') + self.lineTimeInfo = [] + #self.id = None + self.dataFile = input + for line in open(input): + self.lineTimeInfo.append(LineTimeInfo(line, 0)) + + def GetRomName(self): + return "Unknown" + + def GetRunId(self): + return None + + def GetSummary(self): + return "" + + def GetReportFileName(self): + return "Runtest-Summary.txt" diff -r 2c1e559d48bf -r f24810eebc6b tools/e32test-driver/rtest.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/e32test-driver/rtest.py Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,246 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . + +# RTestParser represents the results of running an RTest testsuite on the target in terms of RTest +# objects. Each RTest object captures the LineTimeInfo associated with the test and can determine +# whether the test errored, failed or passed. It also provides further information such as the name of +# the test and how long it took to gather the output from the test (which is a crude estimate of how long +# it took to run the test. It can provide various useful bits of information like the line number in the +# raw test data of a given line and the 'context' of a failure (in terms of the lines in the raw data). + +import sys + +import re + +import qemuruntest + +startRTestPattern = re.compile('RTEST TITLE:') +bmSuiteFailurePattern = re.compile('Error:') +endRTestPattern = re.compile('RUNTESTS: Test') +failedRTestPattern = re.compile('RUNTESTS: Test .* FAIL') +erroredRTestPattern = re.compile('RUNTESTS: Test .* ERROR') +nameRTestPattern = re.compile('RUNTESTS: Test (\w+)') +testSuiteEndingPattern = re.compile('RUNTESTS: Elapsed') + +class NoRTestsFound(Exception): + def __init__(self, parser): + self.parser = parser + + def __str__(self): + return "No test results found in output from running '%s' rom image" % (self.parser.GetRomName()) + + def GetParser(self): + return self.parser + +class RTestEndMissing(Exception): + def __init__(self, rtest): + self.rtest = rtest + + def __str__(self): + return "Could not find end of test started on line %d: '%s'" % (self.rtest.GetLineNumber(0), self.rtest.GetLine(0)) + + def GetParser(self): + return self.parser + + def GetIndex(self): + return self.index + +class RTestNameMissing(Exception): + def __init__(self, rtest, line): + self.rtest = rtest + self.line = line + + def GetRTest(self): + return self.rtest + + def __str__(self): + return "Could not find RTest name in line '%s'" % (self.line) + + def GetParser(self): + return self.parser + + def GetLine(self): + return self.line + +class RTest(object): + def __init__(self, parser, lineTimeInfo, startLine = 0): + """return new RTest instance""" + self.parser = parser + self.lineTimeInfoList = [] + self.lineTimeInfoList.append(lineTimeInfo) + self.timeTaken = None + self.result = None + self.name = None + self.startLine = startLine + #line = lineTimeInfo.GetLine() + #print >> sys.stdout, line + + def __str__(self): + return self.GetName() + " " + self.GetResult() + + def Consume(self,lineTimeInfoList, start): + newStart = start; + for i in range(start, len(lineTimeInfoList) - 1): + lineTimeInfo = lineTimeInfoList[i] + self.lineTimeInfoList.append(lineTimeInfo) + line = lineTimeInfo.GetLine() + newStart = newStart + 1 + if self.EndOfTestp(line): + break + else: + raise RTestEndMissing(self) + + return newStart + + def EndOfTestp(self,line): + return re.match(endRTestPattern, line) != None + + def FailedTestp(self,line): + return re.match(failedRTestPattern, line) != None + + def ErroredTestp(self,line): + return re.match(erroredRTestPattern, line) != None + + def GetTimeTaken(self): + if self.timeTaken == None: + self.timeTaken = self.lineTimeInfoList[-1].GetTime() - self.lineTimeInfoList[0].GetTime() + return self.timeTaken + + def GetResult(self): + if self.result == None: + line = self.lineTimeInfoList[-1].GetLine() + if self.FailedTestp(line): + self.result = 'Failed' + elif self.ErroredTestp(line): + self.result = 'Errored' + else: + self.result = 'Passed' + return self.result + + def Failedp(self): + return self.GetResult() == 'Failed' + + def Erroredp(self): + return self.GetResult() == 'Errored' + + def Passedp(self): + return self.GetResult() == 'Passed' + + def GetName(self): + if self.name == None: + try: + self.name = self.ParseName() + except RTestNameMissing, x: + print >> sys.stderr, "WARNING: ", x + self.name = "RTEST @ line %d" % (x.GetRTest().GetLineNumber(0)) + return self.name + + def ParseName(self): + line = self.lineTimeInfoList[-1].GetLine() + m = re.match(nameRTestPattern, line) + if m != None: + return m.group(1) + else: + raise RTestNameMissing(self, line) + + def GetLineNumber(self, i): + return self.startLine + i + + def GetLine(self, index): + return self.lineTimeInfoList[index].GetLine() + + def ErrorContext(self): + if self.Failedp(): + return map(qemuruntest.LineTimeInfo.GetLine, self.lineTimeInfoList[-5:-1]) + else: + return [] + + +class RTestParser(object): + def __init__(self, testRunner, lineTimeInfoList = None): + self.testRunner = testRunner + if lineTimeInfoList == None: + self.lineTimeInfoList = testRunner.GetResults() + else: + self.lineTimeInfoList = lineTimeInfoList + self.rtestList = [] + self.result = None + + def Parse(self): + index = 0 + end = len(self.lineTimeInfoList) + self.rtestList = [] + testSuiteComplete = False + testErroredp = False + + # find first test + while index < end: + lineTimeInfo = self.lineTimeInfoList[index] + index += 1; + line = lineTimeInfo.GetLine() + if self.StartOfTestp(line): + break + if self.ErroredTestp(line): + self.rtestList.append(RTest(self, lineTimeInfo, index-1)) + else: + raise NoRTestsFound(self) + + try: + while index < end: + # NB making startLine index means that line number are based at 1 rather than 0 + rtest = RTest(self, lineTimeInfo, startLine = index) + self.rtestList.append(rtest) + index = rtest.Consume(self.lineTimeInfoList, index) + + if self.TestSuiteEnding(self.lineTimeInfoList[index].GetLine()): + testSuiteComplete = True + break + + while index < end: + lineTimeInfo = self.lineTimeInfoList[index] + index += 1; + line = lineTimeInfo.GetLine() + if self.StartOfTestp(line): + break + if self.ErroredTestp(line): + self.rtestList.append(RTest(self, lineTimeInfo, startLine = index)) + except RTestEndMissing, x: + print >> sys.stderr, "WARNING: ", x + return testSuiteComplete + + def StartOfTestp(self,line): + if re.match(startRTestPattern, line) != None: + return True + if re.match(bmSuiteFailurePattern, line) != None: + return True + return False + + def ErroredTestp(self,line): + if re.match(erroredRTestPattern, line) != None: + return True + + def TestSuiteEnding(self,line): + return re.match(testSuiteEndingPattern, line) != None + + def GetRTests(self): + return self.rtestList + + def GetLine(self,index): + return self.lineTimeInfoList[index] + + def GetRomName(self): + return self.testRunner.GetRomName() diff -r 2c1e559d48bf -r f24810eebc6b tools/e32test-driver/rtestreport.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/e32test-driver/rtestreport.py Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,78 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . + +# A simple report generator for the results of running an RTest testsuite. +# + +import sys +import qemuruntest +import rtest + +class RTestReport(object): + def __init__(self, testRunner, reportFileRoot = None): + self.testRunner = testRunner + self.reportFileRoot = reportFileRoot + + def SummariseErrors(self, file = sys.stdout ): + print >> file, "%d errors were detected while running rom %s :" % (len(self.erroredTests), self.parser.GetRomName()) + for e in self.erroredTests: + print >> file, e.GetName() + print >> file, "\n" + + def SummariseFailures(self, file = sys.stdout ): + print >> file, "%d failures were detected while running rom %s :" % (len(self.failedTests), self.parser.GetRomName()) + for e in self.failedTests: + print >> file, e.GetName() + for l in e.ErrorContext(): + print >> file, "\t%s" %(l) + print >> file, "\n" + + def SummarisePassed(self, file = sys.stdout ): + print >> file, "The following %d tests passed while running rom %s (times are approximate):" % (len(self.passedTests), self.parser.GetRomName()) + for e in self.passedTests: + print >> file, e.GetName(), " : ", e.GetTimeTaken(), "seconds" + print >> file, "\n" + + def OpenReportFile(self): + name = self.reportFileRoot + if not name: + name = self.testRunner.GetReportFileName() + return open(name, 'w') + + def GetReportFileName(self): + return self.reportFileName + + def PrepareReport(self): + self.parser = rtest.RTestParser(self.testRunner) + try: + self.parser.Parse() + except rtest.NoRTestsFound, x: + print x + sys.exit(1) + self.failedTests = filter(rtest.RTest.Failedp, self.parser.GetRTests()) + self.erroredTests = filter(rtest.RTest.Erroredp, self.parser.GetRTests()) + self.passedTests = filter(rtest.RTest.Passedp, self.parser.GetRTests()) + + def WriteReport(self, file = sys.stdout): + self.PrepareReport() + print >> file, self.testRunner.GetSummary() + self.SummariseErrors(file) + self.SummariseFailures(file) + self.SummarisePassed(file) + return 0 + + diff -r 2c1e559d48bf -r f24810eebc6b tools/e32test-driver/runtests.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/e32test-driver/runtests.py Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,99 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . + +# Provides 'ui' for running RTests on target and generating a report of the results. +# Uses qemuruntest to run the tests and rtestreport to generate the results. + +import glob +import sys +import os.path + +from optparse import OptionParser + +import qemuruntest +import rtestreport + +def ParseOptions(): + optParser = OptionParser() + optParser.add_option("-b", "--board", action="store", type="string", default="syborg") + optParser.add_option("-c", "--cpu", action="store", type="string", default="cortex-a8") + optParser.add_option("-d", "--display", action="store_true", dest="displayp") + optParser.add_option("-i", "--input", action="store", type="string") + optParser.add_option("-o", "--output", action="store", type="string") + optParser.add_option("-q", "--qemu", action="store", type="string", dest="qemupath", default="qemu-system-arm.exe") + optParser.add_option("-r", "--rom", action="store", type="string", default="syborg.e32test.a8.urel.elf") + optParser.add_option("-s", "--summary", action="store", type="string") + + return optParser.parse_args() + +def main(): + errors = False + (options, args) = ParseOptions() + + if not options.input: + gl = glob.glob(options.qemupath) + if len(gl) == 0: + gl = glob.glob(options.qemupath + ".exe") + + if len(gl) == 0: + print >> sys.stderr, "ERROR: can't find qemu executable %s" % (options.qemupath) + errors = True + else: + qemupath = gl[0] + + gl = glob.glob(options.rom) + if len(gl) == 0: + print >> sys.stderr, "ERROR: can't find ROM image %s" % (options.rom) + errors = True + else: + rompath = gl[0] + + if errors: + sys.exit(1) + + output = options.output + if output == None: + output = rompath + + runner = qemuruntest.QemuTestRunner(qemupath, options.cpu, rompath, board = options.board, displayp = options.displayp, dataFile = output) + runner.Run() + else: + gl = glob.glob(options.input) + if len(gl) == 0: + print >> sys.stderr, "ERROR: can't find input file %s" % (options.input) + sys.exit(1) + + input = gl[0] + runner = qemuruntest.PseudoRunner(input) + + testReporter = rtestreport.RTestReport(runner, reportFileRoot = options.summary) + reportFile = False + status = 1 + try: + reportFile = testReporter.OpenReportFile() + status = testReporter.WriteReport(reportFile) + except Exception, x: + print >> sys.stderr, x + status = 1 + if reportFile: + reportFile.close() + + return status + + +if __name__ == "__main__": + main() diff -r 2c1e559d48bf -r f24810eebc6b tools/e32test-driver/setup.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/e32test-driver/setup.py Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,23 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . + +# Script for 'compiling' runtests app into a distributable collection of files for windoze using py2exe + +from distutils.core import setup +import py2exe + +setup(console=['runtests.py']) diff -r 2c1e559d48bf -r f24810eebc6b tools/e32test-driver/watchdog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/e32test-driver/watchdog.py Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,46 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . + +# Implements a 'simple' watchdog built on top of the Timer class from +# the Threading module. +# After a specified interval a WatchDog will invoke a specified function. +# At any point the WatchDog can be Reset, which means the countdown will start from scratch. +# WatchDogs can also be Started and Stopped. +# NB the WatchDog has no idea what the function it invokes will do. + +import threading + +class WatchDog(object): + def __init__(self, interval, function): + self.interval = interval + self.function = function + self.Watcher() + + def Watcher(self): + self.timerThread = threading.Timer(self.interval, self.function) + + def Start(self): + self.timerThread.start() + + def Stop(self): + self.timerThread.cancel() + + def Reset(self): + self.Stop() + self.Watcher() + self.Start() + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/README.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/README.txt Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,15 @@ +The ELF4ROM command line tool and libraries. This tool is used to convert Symbian ROM images +into debuggable elf files. See docs/wiki/ELF4ROM.doc for more information. + +ELF4ROM depends on the following libraries; + +* boost/program_options +* boost/regex +* boost/filesystem +* libelf +* libdwarf + +Supported libelf and libdwarf can be found in the libs/ folder +Boost can be downloaded and built from http://www.boost.org/ + +On windows please use mingw or cygwin to build. diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/COPYING --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/COPYING Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,31 @@ + +David Anderson: December 2006 +The code in the dwarfdump directory is (if you look +in each file) covered by the GPL (not the LGPL). The +DWARFDUMPCOPYRIGHT file, though, said (before December 24, +2006) the copyright is LGPL. There is no doubt in my (David +Anderson) mind that the intent was always that dwarfdump be +GPL and the copyright markings in each file are correct. + +There are three files marked with the LGPL: tag_tree.list +tag_attr.list acconfig.h. These markings are left as is and +these are are therefore LGPL files. + +The DWARFDUMPCOPYRIGHT file now (Dec 24 2006) has both +copyrights and an explanation of where each applies. + + + +------------------------------------------- +The text present for years, thru Dec 23, 2006: +The files: + dwarfdump.c + and all the .h and .c files in this implementation of + dwarfdump are copyrighted according to the file + DWARFDUMPCOPYRIGHT. + + + +$Source: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/COPYING,v $ +$Revision: 1.1 $ +$Date: 2001/01/16 17:47:55 $ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/ChangeLog --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/ChangeLog Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,108 @@ +2007-12-09 DavidAnderson + * print_sections.c print_frames.c: Forgot to commit yesterday. + yesterday's commit includes renaming _dwarf_fde_section_offset + _dwarf_cie_section_offset, _dwarf_print_lines, _dwarf_ld_sort_lines + to dwarf_* form while retaining support for the now obsolete + _dwarf_* form. +2007-12-08 DavidAnderson + * config.h.in, configure.in: Latest linux libelf.h requires + _GNU_SOURCE to get off64_t defined so dwarfdump compiles. + Only define _GNU_SOURCE if libelf.h defines off64_t. + Regenerated configure. + * config.guess, config.sub: Updated to 2.61 + * acconfig.h: Deleted, removing autoconf complaint. +2007-10-15 DavidAnderson + * print_die.c (clean_up_die_esb): New function + cleans up malloc space. + * print_reloc.c (clean_up_syms_malloc_data): New function + cleans up malloc space. + * dwarfdump.c (main): Call new cleanup functions at end. + * globals.h: Declare new cleanup functions. + +2007-09-04 DavidAnderson + * print_die.c (print_attribute): For DWARF4: DW_AT_high_pc: + add qualifier to value when the value is an offset from + DW_AT_low_pc (thus not itself a address). + Update the address of the FSF. + * print_frames.h DWARFDUMPCOPYRIGHT print_sections.c + print_reloc.c dwarfdump.c tag_tree.c tag_attr.c + esb.c esb.h makename.c acconfig.h dwconf.c makename.h + dwconf.h globals.h print_frames.c: + Update the address of the FSF. + +2007-07-03 DavidAnderson + * print_sections.c (dump_block): Removed superfluous return byte from + printed characters. Removed unused variables. + * print_die.c: A little refactoring for clarity. + * globals.h: dwarfdump_print_one_locdesc() is now a + global-to-dwarfdump function. + * print_frames.c: Now (with -v) prints dwarf expression bytes + in frame expressions readably. +2007-07-02 DavidAnderson + * dwarfdump.c: Add new -R option for 'generic' register sets. + * dwarfdump.1: document -R, add new -x documentation. + * dwconf.c: Set up -R configuration. Slight revision of + register printing code. + * dwconf.h: Interface to register name printing simplified. + * print_frames.c: Use the simpler register name interface. + * dwarfdump.conf: Add new 'generic' abi for up to 1000 registers. + +2007-07-01 DavidAnderson + * print_frames.c: For DW_CFA_def_cfa_sf & DW_CFA_def_cfa_offset_sf + print a computed data alignment factor. +2007-06-29 DavidAnderson + * dwarfdump.1: Corrected spelling error. +2007-05-25 DavidAnderson + * dwconf.h dwconf.c: Changed field name to + cf_named_regs_table_size as old name was less than clear. + * dwarfdump.c: Call frame table setup with + cf_table_entry_count not cf_named_regs_table_size. The newly + renamed field makes it clearer the call was wrong. +2007-05-04 DavidAnderson + * print_die.c: printing of global offset of DIEs + with -G is now more in the style of previous output. +2007-04-18 Chris Quenelle + * Makefile.in: + - use $(srcdir) for files in source directory + - support running rules in parallel by + - use different tmp file names in different rules. + - use more accurate target for dwarf_names.{c,h} + * dwarf_names.awk: Enhance script to be able to generate either + #define-style headers or enum-style headers + * dwarfdump.c: dump most everything by default if no arguments + are given to dwarfdump. This seems to be a more useful default + than showing nothing at all. Also add a -G option to show + the (G)lobal section offset for each die within an a.out. If you + think you're seeing data corruption inside a .debug_info + section, this is a useful option to have. + * print_die.c: Support compressed integer blocks. This is an + array (DW_FORM_block) of LEB numbers used as part of a Sun + extension, DW_AT_SUN_func_offsets. Also add support for + a new dwarf enum DW_ATCF_xxxx. This is used in DW_AT_SUN_cf_kind. + Also, fix DW_AT_upper_bound so it can be a constant or a location + list. DW_AT_count and DW_AT_data_member_location should also be + fixed eventually. + * print_sections.c: Changes to support zero-padding in the middle of + section data. Change offset labels to be a little more clear. + Not sure about the get_str failure. + * tag_tree.list: DW_TAG_compile_unit can contain a DW_TAG_namespace +2007-04-10 David Anderson + * print_reloc.c dwarfdump.c print_frames.c: Unified + copyright to the SGI form. No copyright change. + +2007-04-06 David Anderson + * print_die.c (print_die_and_children): Increase static + depth of die stack. Notice if it overflows and + print error. +2007-02-23 David Anderson + * print_reloc.c: 2 lines added (long) cast in printf + and made %3ld instead of %3d to fix compiler warning. + * print_frames.c: newline was missing from the output. + Thanks to Chris Quenelle for noticing. +2007-02-20 David Anderson + * print_frame.c (print_frame_inst_bytes): Fixed + an off by one error (several places) + when printing dwarf expressions and added commentary about it. + Thanks to Julian Seward for pointing out it was off by one. + * dwarfdump.c (print_error): added fflush of stdout, stderr + where we are going to exit right away anyway. diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/ChangeLog2006 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/ChangeLog2006 Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,332 @@ +2006-12-24 David Anderson + * DWARFDUMPCOPYRIGHT: Added GPL copyright text with + explanation of the intended content. + * COPYING: added text explaining confusion of GPL vs LGPL. + Thanks to Chris Quenelle for pointing out the disconnect + between DWARFDUMPCOPYRIGHT and the source files in dwarfdump. +2006-12-21 David Anderson + * tag_tree.list: add tags to make allowed list more complete. + Omission noticed by Marcel Mettes. +2006-06-14 David Anderson + * print_frames.c: Clean up printing of augmentation data by + eliminating dangling 0x (for eh_frame). +2006-04-28 David Anderson + * dwarfdump.conf: Now has x86_64 register names. + x86_64 with help from Tom Hughes (verified + from independent sources). + Added m68k register names and refined x86 list + by looking at various information-sources. +2006-04-18 David Anderson + * *.c: Ran indent so all now follow a standard look. + * dwconf.c: Added fclose(conf_stream). +2006-04-18 David Anderson + * dwarfdump.c: Forgot to call key new functions for + handling variable-size frame data and different + frame rule initialization value. + * dwconf.c: Add a default print for CFA in case of + an omission in dwarfdump.conf. + * dwarfdump.conf: Move setup and rename the ABIs slightly. +2006-04-17 David Anderson + * dwarfdump.conf: Correct typos. Remove some register names. + * dwarfdump.c: Fix compiler warnings, fix -x option usage message. + * dwconf.h: Fix compiler warnings by changing types. + * dwconf.c: Change error checking so we check all errors, do + not stop at first error. Ran indent. Added code to check + for extra junk after operand(s). + * print_frames.c: Fix compiler warnings. + * Makefile.in: get used in install rule and creating + places to search for dwarfdump.conf +2006-04-16 David Anderson + * dwarfdump.conf: New dwarfdump configuration file. Makes using frame + information easy to read and correct for any ABI/ISA + without rebuilding dwarfdump. + * Makefile.in: Added new files dwconf.h dwconf.c + * dwconf.h dwconf.c: New files implement reading dwarfdump.conf + and help print_frames.c print frame information correctly + for ABIs specified at runtime. + * dwarfdump.1: document -x commands. + * globals.h: Minor changes to support dwarfdump.conf + * print_frames.c: Major changes to support a run-time description of + the frames info and dwarfdump.conf. + * print_frames.h: Changes to support a run-time description of + the frames info and dwarfdump.conf. + * print_sections.c: Minor tweaks to support a run-time + description of the frames info and dwarfdump.conf. + +2006-03-31 David Anderson + * Makefile.in globals.h print_sections.c: Refer to new + print_frames.h print_frames.c. + * print_frames.h print_frames.c: Extract cie, fde printing + to separate file, separating loop logic from the printing + of an entry from the loop. +2006-03-31 David Anderson + * dwarfdump.c global.h print_sections.c: Preparing for + dwarf3 frame interface. + * print_die.c: Corrects handling of DW_AT_encoding (etc) value. +2006-03-29 David Anderson + * print_sections.c: define DWARFDUMP_TURN_OFF_MIPS_REG_NAMES + at compile time + to turn off the MIPS register names printing. Instead + (aside from cfa) use a name like r4 (where the DWARF + register number follows the letter 'r'). + Indent. Initialize some local variables at declarations. +2006-03-13 David Anderson + * print_sections.c: Now gets gnu eh_augmentation data by calling + dwarf_get_cie_augmentation_data() or dwarf_get_fde_augmentation_data() + and prints it (use -v to see cie data). + Now prints DWARF3 frame information. +2006-03-08 David Anderson + * print_sections.c: Add 'break;' at line 710. + Thanks to Richard Stuckey for noticing. +2005-12-01 David Anderson + * dwarf_names.awk: use snprintf instead of sprintf for safety. +2005-12-01 David Anderson + * Makefile.in: Build attr/tag trees with + individual commands to catch build errors. + * tag_attr.c,tag_tree.c: Verify that + tables fit in the generated C code and check for + format errors in the *.list files. + * tag_attr.list, tag_tree.list: Added some valid entries. + * globals.h: add DWARF_ERROR3 macro for better diagnostics. + * print_die.c: Show both sides of questionable tag relation + in CHECK -k diagnostic output. + +2005-11-25 David Anderson + * print_die.c: DW_AT_stride_size changed to DW_AT_bit_stride, + added DW_AT_byte_stride. + * tag_attr.c,tag_tree.c: fixed array size now a #define for + readability. + * tag_attr.list: Added DWARF3 attributes, also new TAGs. + * tag_tree.list: Added DWARF3 TAGs. + +2005-11-08 David Anderson + * makename.c: remove non-standard malloc.h include, + stdlib.h suffices and is already included. + +2005-10-24 David Anderson + * tag_attr.c tag_tree.c: added DWARF3 TAGs to string array. + +2005-08-01 David Anderson + * Makefile.in: Add esb.o and test rule (test code for esb.c). + * dwarfdump.c: Remove old static buffer initialization. + * print_die.c: Use esb now, avoid crash due to long loclist + overrunning static buffer. Uses snprintf now, not sprintf. + snprintf is for safety. + * esb.h esb.c: Adding extensible string buffer (esb) code. + * testesb.c: Test code for esb.c. + * print_reloc.c: size field is now Elf64_Xword for + Elf64 as Elf64_Word is only 32 bits. + +2005-07-15 David Anderson + * dwarfdump.c: Add print of .debug_pubtypes, remove + erroneous dealloc after dwarf_formstring() call. + * globals.h: Add declarations for .debug_pubtypes print. Add + declaration for full dealloc. + * print_die.c: Remove erroneous dealloc after dwarf_formstring() call. + * print_exception_tables.c: Call dwarf_fde_cie_list_dealloc() + for complete dealloc. + * print_sections.c: Remove incorrect dealloc() call. + Add calls to new dealloc routines. Add support of .debug_pubtypes + print. +2005-07-14 David Anderson + * print_sections.c (print_line_numbers_this_cu): Use new + dwarf_srclines_dealloc() for deallocation after + dwarf_srclines() called. + +2005-04-13 David Anderson + * print_sections.c: Factors out common print code into + a new routine. Avoid indexing past end of register names + array. Adds checks and prints so that certain errors + in pubnames-like sections are printed usefully (and dwarfdump + then stops if libdwarf gave an error). + +2005-03-21 David Anderson + * dwarfdump.c: Add -F flag to + request .eh_frame section print. Changed -f flag meaning + to print .debug_frame only. -a flag no longer + prints .debug_frame by default. + * print_sections.c: avoid printing an eh_frame we don't understand. + Add new information per CU when printing line info: specifically + the line section offset. + * globals.h: Added arguments to print_frames() for -F flag. + +2005-03-18 David Anderson + * print_sections.c: Correct macro section printing. + +2004-10-28 David Anderson + * DWARFDUMPCOPYRIGHT config.h defs.h dwarfdump.c globals.h + makename.c makename.h print_die.c print_exception_tables.c + print_reloc.c print_sections.c tag_attr.c tag_attr.list + tag_tree.c tag_tree.list: Copyright update, SGI + corporate address change. + +2004-10-26 David Anderson + * acconfig.h: removed. Was old style autoconf usage. + * configure.in: Updated AC_DEFINE usage, adding args 2 & 3. + * config.guess: Updated. timestamp='2004-06-11'. + * config.sub: Updated. timestamp='2004-03-12'. + * configure config.h.in: regenerated with autoconf 2.58. + +2004-05-14 David Anderson + + * print_die.c (print_die_and_children): Change to iteration + on siblings (still recursing on children). + + +2004-03-30 David Anderson + * dwarfdump.c (main): getopt() string should contain k:g + not kg: Thanks to Peter Seiderer for pointing this out. + +2003-12-31 David Anderson + * README: Added configure example. + * Makefile.in: Removed bogus LIBS line, updated copyright date. + * acconfig.h: Added LGPL copyright to match libdwarf + Silly, but it matches libdwarf version boilerplate. + * config.guess config.sub: new versions from automake-1.6. + * config.h.in configure: Regenerated. + + +2003-10-06 David Anderson + * dwarfdump.c print_sections.c: applied indent(1). + * print_die.c: applied indent and added ; after + invocations of macros PUSH_DIE_STACK POP_DIE_STACK SPACE + as these were confusing indent a bit. + The indent control file .indent.pro contained: + -bad -bap -nbbo -br -ce -brs + -l72 -lc72 -hnl -nprs + -fca -i4 -lp -psl -npcs + + + +2003-10-02 David Anderson + * dwarfdump.c: Add -g to indicate use of older + location entry code in libdwarf. So dwarf_loclist + and dwarf_loclist_n are testable. + * globals.h: Added use_old_dwarf_loclist flag so one + can choose the old dwarf_loclist() interface. + For testing. + * print_die.c: Rearranged to avoid code duplication. + Now supports .debug_loc fully. + * print_sections.c: Prints .debug_loc now. + +2003-09-29 David Anderson + + * print_die.c: with -v, print 'loclist' start and + end addr and also a hint that DW_FORM_indirect is used. + No change for normal output (for now). + +2003-05-19 David Anderson + * dwarfdump.c call dwarf_srcfiles() to get file names + per cu and pass down to die print routines. + Removed incorrect tests for when to print ".debug_info", + leaving simpler test. + * print_die.c globals.h: print file name (from line info) + with DW_AT_decl_file, adding data from dwarf_srcfiles + to argument list of a few routines to make that possible. + * print_sections.c: moved "line number info" string print so + it prints for -v as well as normal line ouput. + +2002-10-23 Amaury Le Leyzour amaury@sgi.com + * print_sections.c (print_weaknames): Changed + DW_DLA_TYPENAME to DW_DLA_WEAK at dwarf_dealloc(). + +2002-10-22 Tom Hughes + * print_sections.c: macro printing now supported. + * dwarfdump.c: removed erroneous dwarf_dealloc() + of string returned by dwarf_errmsg(). + +2002-11-22 David Anderson + * dwarf_names.awk at_list.awk: Allow an name to have two + spellings so the historical name preserved yet the dwarf3 + version is supported. First name seen is used/reported + by dwarfdump. + * dwarf.h: DW_TAG_template_type_param(eter) + DW_TAG_template_value_param(eter) DW_AT_namelist_itm(s) + are the ones with alternate spellings now. + Added Universal Parallel C TAGs/Attributes in + user namespace. + * tag_attr.c tag_attr.list tag_tree.c tag_tree.list: + Use the DW_TAG_template_* dwarf3 spellings. + + +2002-05-08 David Anderson + * tag_attr.list dwarf.h: DW_AT_namelist_items is + wrong, changed to DW_AT_namelist_item + +2002-04-29 Stephen Clarke + * dwarfdump.c (main): #ifdef for __CYGWIN__ on open(). + +2001-06-14 David Anderson + + * print_sections.c: Calling the new libdwarf function + dwarf_get_arange_cu_header_offset() so we can print + the cu header offset for aranges. + + +2000-07-14 Fred Fish + + * configure.in (LOCATION_OF_LIBELFHEADER): Fix typo for configure + variable to be tested and enclose libelf/libelf.h in <>. + * configure: Regenerated. + +2000-07-10 Fred Fish + + * Makefile.in (install): Install dwarfdump.1 from $(srcdir). + +2000 June 12 davea@sgi.com + print_sections.c the DW_CFA_offset_extended print + did not multiply by data-alignment factor in the + -v -v detailed output. + And the offsets used %2d when the values were + unsigned int, so now %2u. + + And not all cfa prints of values had + necessarily a type to match + %llu or %lld where required. Depended on the size of Dwarf_Signed + and Dwarf_Unsigned. + So now explicitly use cast to the + right type to match the % format. +2000 April 13 davea@sgi.com + print_sections.c - 1.56 + - A single byte of zero is a perfectly legitmate null + abbreviation entry (in .debug_abbrev) + now we print those directly and avoid a warning + from dwarfdump + + print_die.c - 1.42 + - Explain what combo checker is doing and make it + more maintainable (and fix bug which would + not be hit, but was real enough (in combo checker), + using too large a number as highest tag number). + + tag_tree.list - 1.2 + - Add valid parent/child relationships so checker + does not report valid entries as bogus. + + + + +2000 Feb 24 + Jason Merrill noticed that gcc did + not like gcc -E foo.list, so incorporated his fix so + now the Makefile.in makes a link and does gcc -E _tmp.c + +2000 Jan 26 + elena.demikhovsky@intel.com noticed that 3 statements in + print_sections.c got warnings from the compiler + she was using. Simple casts (provided by her) fixed these. + +1999 July 21 + davea@sgi.com + print_sections changed to allow printing + of dwarf-ish egcs c++ .eh_frame data + + +1999 June 14 + Fred Fish fnf@ninemoons.com contributed + autoconf'ing of the libdwarf and dwarfdump source. + + + +1999 June 10 + ChangeLog started. davea@sgi.com David Anderson diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/DWARFDUMPCOPYRIGHT --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/DWARFDUMPCOPYRIGHT Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,85 @@ + +========The dwarfdump copyright======= + +The full text of the GPL version 2 is provided in the file GPL.txt. + +Nearly all the files in this directory have contained a GPL +copyright, not an LGPL copyright, for years. The following +is an example of that copyright as used in the dwarfdump +source, and is what SGI always intended (in David +Anderson's opinion) to have present in +the DWARFDUMPCOPYRIGHT file. (tag_tree.list tag_attr.list +acconfig.h have long been marked LGPL and therefore the LGPL +copyright, not GPL, applies to those three files.) This GPL +copyright text added here to DWARFDUMPCOPYRIGHT Dec 4, 2006 + + Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + +The following was the entire content of this file before +December 24 2006, Being the LGPL text this is in conflict +with the individual source files and I (David Anderson) +believe the source file copyright was intended for dwarfdump +not the LGPL source directly following this note. However the +3 files tag_tree.list tag_attr.list acconfig.h have long been +marked LGPL and the following copyright applies to those three. + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/GPL.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/GPL.txt Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public 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. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/Makefile.in Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,131 @@ +# +# Makefile for dwarfdump +# This is made very simple so it should work with +# any 'make'. + +# + +srcdir = @srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = $(exec_prefix)/bin +libdir = $(exec_prefix)/lib +mandir = @mandir@ +man1dir = $(mandir)/man1 + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +SHELL = /bin/sh +CC = @CC@ +AR = @AR@ +ARFLAGS = @ARFLAGS@ +RM = rm +RANLIB = @RANLIB@ +DEFS = @DEFS@ +LIBS = @LIBS@ -L../libdwarf -ldwarf -lelf +INCLUDES = -I. -I$(srcdir) -I$(srcdir)/../libdwarf +CFLAGS = @CFLAGS@ $(INCLUDES) -DCONFPREFIX=${libdir} +LDFLAGS = @LDFLAGS@ $(LIBS) + +# ../libdwarf gets us to local headers + +DIRINC = $(srcdir)/../libdwarf +INSTALL = cp + +binprefix = + +GEN_CFILES = \ + dwarf_names.c + +OBJECTS = tag_tree_table.o \ + tag_attr_table.o \ + dwarfdump.o \ + dwconf.o \ + esb.o \ + print_sections.o \ + print_die.o \ + print_reloc.o \ + print_frames.o \ + dwarf_names.o \ + makename.o +GEN_HFILES = \ + dwarf_names.h \ + _tag_tree_table.c \ + _tag_attr_table.c + +all: dwarfdump + +$(OBJECTS): $(GEN_HFILES) $(srcdir)/globals.h $(srcdir)/print_frames.h + +default: $(TARGETS) + + +dwarfdump: $(OBJECTS) + $(CC) $(CFLAGS) -o $@ $(OBJECTS) $(LDFLAGS) + + +#at_list.i: at_list.awk $(DIRINC)/dwarf.h +# awk -f $(srcdir)/at_list.awk $(DIRINC)/dwarf.h > $@ +#at_list.o: at_list.i +# $(CC) $(CFLAGS) -c at_list.i -o $@ + +_tag_tree_table.c: $(srcdir)/tag_tree.list $(srcdir)/tag_tree.c $(DIRINC)/dwarf.h + $(CC) $(CFLAGS) $(LDFLAGS) -o tag_tree_build $(srcdir)/tag_tree.c + # gcc -E tag_tree.list does not work, so use a .c name + rm -f _tmp1.c && ln -s $(srcdir)/tag_tree.list _tmp1.c + $(CC) $(CFLAGS) -E _tmp1.c \ + | awk '!/^#/ && !/^[ \t]*$$/' > ./tag_tree_build.tmp + ./tag_tree_build $@ + rm -f tag_tree_build .tmp + rm -f tag_tree_build +tag_tree_table.o: _tag_tree_table.c + $(CC) $(CFLAGS) -c _tag_tree_table.c -o $@ + +_tag_attr_table.c: $(srcdir)/tag_attr.list $(srcdir)/tag_attr.c $(DIRINC)/dwarf.h + $(CC) $(CFLAGS) $(LDFLAGS) -o tag_attr_build $(srcdir)/tag_attr.c + # gcc -E tag_attr.list does not work, so use a .c name + rm -f _tmp2.c && ln -s $(srcdir)/tag_attr.list _tmp2.c + $(CC) $(CFLAGS) -E _tmp2.c \ + | awk '!/^#/ && !/^[ \t]*$$/' > ./tag_attr_build.tmp + ./tag_attr_build $@ + rm -f tag_attr_build.tmp + rm -f tag_attr_build +tag_attr_table.o: _tag_attr_table.c + $(CC) $(CFLAGS) -c _tag_attr_table.c -o $@ + +# The file dwarf_names.awk generates BOTH dwarf_names.h and dwarf_names.c +# be careful of the make dependencies here +dwarf_names.h: dwarf_names.awk $(DIRINC)/dwarf.h + rm -f dwarf_names.h dwarf_names.c + awk -f $(srcdir)/dwarf_names.awk $(DIRINC)/dwarf.h > dwarf_names.c +dwarf_names.c: dwarf_names.h + +test: esb.o $(srcdir)/testesb.c + $(CC) -o test $(srcdir)/testesb.c esb.o + ./test + -rm -f ./test + + +install: all + $(INSTALL) dwarfdump $(bindir)/dwarfdump + $(INSTALL) $(srcdir)/dwarfdump.1 $(man1dir)/dwarfdump.1 + $(INSTALL) $(srcdir)/dwarfdump.conf $(libdir)/dwarfdump.conf + +uninstall: + -rm -f $(bindir)/dwarfdump + -rm -f $(man1dir)/dwarfdump.1 + -rm -f $(libdir)/dwarfdump.conf + +clean: + rm -f *.o dwarfdump dwarf_names.h *~ _tag_attr_table.c _tag_tree_table.c dwarf_names.c + +distclean: clean + rm -f config.log config.h config.cache config.status dwarf_names.c + +shar: + @echo "shar not set up yet" +dist: + @echo "dist not set up yet" diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/NEWS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/NEWS Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,111 @@ +December 8, 2007 + Had to add an ugly configure conditional as libelf has + unconditional use of off64_t in recent libelf.h +July 3, 2007 + Now with -v dwarf expression blocks in frame operations + are printed expanded out. +July 2, 2007 + Added a new abi -x abi=general usable for any cpu with + up to 1000 registers. +May 7, 2007 + Sun Microsystems contributes new dwarf.h extensions and a new -G option + to dwarfdump -i (so one can see the 'global' offset to DIEs). + Thanks to Chris Quenelle of Sun. +April 17, 2006 + New -x name= -x abi= and configuration file + enable sensible printing of a wide range of .debug_frame eh_frame + correctly without recompiling dwarfdump or touching libdwarf.h or + dwarf.h. +March 29, 2005 + Now handles DWARF3. For non-MIPS objects, the list of register + names in print_sections.c is not appropriate, #define + DWARFDUMP_TURN_OFF_MIPS_REG_NAMES to turn off the MIPS names. +December 1, 2005 + Added new DWARF3 TAGs and ATtributes to the -k lists, + clarified the -k reporting, and made the build more robust + in the face of errors in the *.list relationship-spec-files. + +August 1, 2005 + Now print_die.c deals with long loclists without a coredump. + Added esb.h esb.c (and testesb.c for testing) to encapsulate + getting space for possibly-long strings. + Now print_die.c uses snprintf() not sprintf (hopefully this + will not inconvenience anyone, snprintf() has been available + on most systems for years now). + Altered print of location lists a little bit - for better appearance. + +July 15, 2005 + Now completely frees all allocated memory. Various + routines were not calling dealloc() code and + new libdwarf dealloc routines are now used where those + are needed. + + Now prints DWARF3 .debug_pubtypes section (with -a or -y). + The .debug_pubtypes section and SGI-specific .debug_typenames + are equvalent so they are treated alike. + +Mar 21, 2005 + The -f flag now prints only .debug_frame data. The .eh_frame section + (GNU exceptions data) now prints with -F (not -a). + Printing gcc 3.3 or 3.4 .eh_frame with zR augmentation + does not work at this time, so do not use -F + to print such an object. + The line section print now prints a CU-DIE offset for each such DIEs + line information. This makes it much easier to correctly associate + -l (or -v -l) output with -v -v -l when debugging a faulty + linetable in an executable. + With -v -v -l (two -v) the output of line info continues to be a + completely different format than zero or one -v, the two-v + form showing the detailed line table opcodes. + With g++ 3.3.3 one sees bad line addresses at times as the + DW_LNE_set_address address for header files do not always + get their relocations applied. I am told this is fixed in 3.4.x. + + +Mar 18, 2005 + In correcting printing of macro information the format + of the macro (-m) output has changed substantially. + Much more complete now. Still could use enhancement. + +Oct 28, 2004 + Updated contact address in copyright: SGI moved 1/4 mile + to a new address: 1500 Crittenden Lane. + +Oct 02, 2003 + Now fully supports .debug_loc section. + +June 14, 2001 + Now calling a new function dwarf_get_arange_cu_header_offset() + in libdwarf and printing the returned cu header offset for + aranges entries. Making it easier to track down internal + errors in the dwarf2 data. Also added small other + consistency checks, printing a message and exit()ing on + error. + +April 14, 2000 + The libdwarf copyright has changed to + version 2.1 of the GNU Lesser General Public License. + Anyone holding a version of libdwarf that was published + before this new copyright + is allowed to use + the copyright published in that earlier libdwarf source + on the earlier source + or to use + this new copyright on the earlier source, + at their option. + +July 21, 1999 + Added gnu extensions to the frame information printer + and handling for egcs eh_frame printing. + libdwarf changes mean this now can print little-endian + object dwarf on a big-endian system and vice-versa. + +December, 1998 + added dwarfdump to the dwarf public source distribution. + +June, 1994 + libdwarf consumer interface changed completely so updated to match. + +May, 1993 + Initial version of dwarfdump for dwarf version 2 + written at sgi. diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/README Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,43 @@ + +To build dwarfdump, first build libdwarf in the neighboring +directory then type + ./configure + make + +To use dwarf or libdwarf, you may want to install dwarf.h and +libdwarf.h somewhere convenient, and you may need the libdwarf +in the accompanying libdwarf directory + +If your headers or libelf/libdwarf are not in the expected places, +use the configure script to access them (and to add other ld +or C flags). +For example, using csh syntax: + setenv PRIVATE_LIBDIR /home/davea/lib + ./configure LDFLAGS="-L$PRIVATE_LIBDIR" \ + CPPFLAGS="-I/home/davea/inc" CFLAGS="-I/home/davea/inc" +Set both CFLAGS and CPPFLAGS so that configure works properly. + +If your primary target cpu architecture ( of objects that you are using +dwarfdump on) is not MIPS, you will probably want to +add -DDWARFDUMP_TURN_OFF_MIPS_REG_NAMES=1 +to CPPFLAGS and CFLAGS to avoid using misleading +register names. See print_sections.c. + + +If $PRIVATE_LIBDIR has both libelf.so and libelf.a, the libelf.so +will be picked up and + "./tag_tree_build: error while loading shared libraries: + libelf.so.0: cannot open shared object file: + No such file or directory" +will probably result. +Either: remove libelf.so.* from your $PRIVATE_LIBDIR +or set LD_LIBRARY_PATH to $PRIVATE_LIBDIR, or use LDFLAGS to +set rpath. Much simpler all around to ensure that $PRIVATE_LIBDIR +only has archive libelf, not shared-library libelf. + + +David Anderson. davea@sgi.com + +$Source: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/README,v $ +$Revision: 1.3 $ +$Date: 2006/03/29 23:26:01 $ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/at_list.awk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/at_list.awk Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,22 @@ +# print code to return attribute name from list of attrs in dwarf.h (the input) +# In case of a duplicate value, accept the first as definitive. +# dwarf2 had a couple ambiguities/mistakes in attribute spelling. +BEGIN { + printf "static int list_of_attrs[] = {\n" + used_pref["0"] = ""; +} +{ + prefix = "DW_AT_" + prefix_len = length(prefix) + if ($1 == "#define" && substr($2,1,prefix_len) == prefix) { + if ( used_pref[ $3] != $3 ) { + printf "\t%s,\n", $2 + used_pref [$3] = $3 ; + } + } +} +END { + printf "\t0\n" # last value + printf "};\n" +} + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/config.guess --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/config.guess Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1504 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2006-11-15' + +# 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 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + x86:Interix*:[3456]*) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T:Interix*:[3456]* | authenticamd:Interix*:[3456]*) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/config.h.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/config.h.in Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,85 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if the elf64_getehdr function is in libelf.a. */ +#undef HAVE_ELF64_GETEHDR + +/* Define to 1 if the Elf64_Rel structure has r_info field. */ +#undef HAVE_ELF64_R_INFO + +/* Define to 1 if you have the header file. */ +#undef HAVE_ELF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_GETOPT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBELF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBELF_LIBELF_H + +/* Define 1 if off64 is defined via libelf with GNU_SOURCE. */ +#undef HAVE_LIBELF_OFF64_OK + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define 1 if plain libelf builds. */ +#undef HAVE_RAW_LIBELF_OK + +/* Define to 1 if you have the header file. */ +#undef HAVE_SGIDEFS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* See if __uint32_t is predefined in the compiler. */ +#undef HAVE___UINT32_T + +/* Define 1 if sys/types.h defines __uint32_t. */ +#undef HAVE___UINT32_T_IN_SYS_TYPES_H + +/* See if __uint64_t is predefined in the compiler. */ +#undef HAVE___UINT64_T + +/* Define to header that first defines elf. */ +#undef LOCATION_OF_LIBELFHEADER + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/config.sub --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/config.sub Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1619 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2006-11-07' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# 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 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/configure --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/configure Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,4694 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.59. +# +# Copyright (C) 2003 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="dwarfdump.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA RANLIB ac_ct_RANLIB AR ac_ct_AR LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF + +Copyright (C) 2003 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + ac_config_headers="$ac_config_headers config.h" + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + +if test $ac_cv_c_compiler_gnu = yes; then + echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5 +echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6 +if test "${ac_cv_prog_gcc_traditional+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_pattern="Autoconf.*'x'" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +Autoconf TIOCGETP +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then + ac_cv_prog_gcc_traditional=yes +else + ac_cv_prog_gcc_traditional=no +fi +rm -f conftest* + + + if test $ac_cv_prog_gcc_traditional = no; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +Autoconf TCGETA +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then + ac_cv_prog_gcc_traditional=yes +fi +rm -f conftest* + + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5 +echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6 + if test $ac_cv_prog_gcc_traditional = yes; then + CC="$CC -traditional" + fi +fi + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + echo "$as_me:$LINENO: result: $AR" >&5 +echo "${ECHO_T}$AR" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 +echo "${ECHO_T}$ac_ct_AR" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + AR=$ac_ct_AR +else + AR="$ac_cv_prog_AR" +fi + + + +/* Define to 1 if the elf64_getehdr function is in libelf.a */ +#undef HAVE_ELF64_GETEHDR + + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + + + +for ac_header in elf.h getopt.h libelf.h libelf/libelf.h sgidefs.h sys/types.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +echo "$as_me:$LINENO: checking for elf64_getehdr in -lelf" >&5 +echo $ECHO_N "checking for elf64_getehdr in -lelf... $ECHO_C" >&6 +if test "${ac_cv_lib_elf_elf64_getehdr+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lelf $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char elf64_getehdr (); +int +main () +{ +elf64_getehdr (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_elf_elf64_getehdr=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_elf_elf64_getehdr=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_elf_elf64_getehdr" >&5 +echo "${ECHO_T}$ac_cv_lib_elf_elf64_getehdr" >&6 +if test $ac_cv_lib_elf_elf64_getehdr = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ELF64_GETEHDR 1 +_ACEOF + +fi + + +if test "$ac_cv_header_elf_h" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define LOCATION_OF_LIBELFHEADER +_ACEOF + +elif test "$ac_cv_header_libelf_h" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define LOCATION_OF_LIBELFHEADER +_ACEOF + +elif test "$ac_cv_header_libelf_libelf_h" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define LOCATION_OF_LIBELFHEADER +_ACEOF + +fi + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include LOCATION_OF_LIBELFHEADER +int +main () +{ +Elf64_Rel *p; int i; i = p->r_info; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ELF64_R_INFO 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +__uint32_t p; p = 3; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE___UINT32_T 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +__uint64_t p; p = 3; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE___UINT64_T 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ + __uint32_t p; p = 3; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE___UINT32_T_IN_SYS_TYPES_H 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include + +int +main () +{ + int p; p = 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_RAW_LIBELF_OK 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#define _GNU_SOURCE +#include + +int +main () +{ + off64_t p; p = 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBELF_OFF64_OK 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + + + + ac_config_files="$ac_config_files Makefile" +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + + + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@CPP@,$CPP,;t t +s,@EGREP@,$EGREP,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@AR@,$AR,;t t +s,@ac_ct_AR@,$ac_ct_AR,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + # Do quote $f, to prevent DOS paths from being IFS'd. + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/configure.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/configure.in Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,58 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(dwarfdump.c) +AC_CONFIG_HEADER(config.h) + +AC_PROG_CC +AC_GCC_TRADITIONAL +AC_PROG_INSTALL +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(AR, ar) +dnl AC_ARFLAGS + + +/* Define to 1 if the elf64_getehdr function is in libelf.a */ +#undef HAVE_ELF64_GETEHDR + + + +AC_CHECK_HEADERS(elf.h getopt.h libelf.h libelf/libelf.h sgidefs.h sys/types.h) +AC_CHECK_LIB(elf,elf64_getehdr, + AC_DEFINE(HAVE_ELF64_GETEHDR,1, + [Define to 1 if the elf64_getehdr function is in libelf.a.])) + +dnl Find out where the elf header is. +if test "$ac_cv_header_elf_h" = yes; then + AC_DEFINE(LOCATION_OF_LIBELFHEADER,[], [Define to header that first defines elf]) +elif test "$ac_cv_header_libelf_h" = yes; then + AC_DEFINE(LOCATION_OF_LIBELFHEADER, [], + [Define to header that first defines elf.]) +elif test "$ac_cv_header_libelf_libelf_h" = yes; then + AC_DEFINE(LOCATION_OF_LIBELFHEADER,[], + [Define to header that first defines elf.]) +fi + +AC_TRY_COMPILE([#include LOCATION_OF_LIBELFHEADER], Elf64_Rel *p; int i; i = p->r_info; ,AC_DEFINE(HAVE_ELF64_R_INFO,1, + [Define to 1 if the Elf64_Rel structure has r_info field.])) +AC_TRY_COMPILE([], __uint32_t p; p = 3; ,AC_DEFINE(HAVE___UINT32_T, + 1,[See if __uint32_t is predefined in the compiler. ])) +AC_TRY_COMPILE([], __uint64_t p; p = 3; ,AC_DEFINE(HAVE___UINT64_T, + 1,[See if __uint64_t is predefined in the compiler. ])) +AC_TRY_COMPILE([#include ],[ __uint32_t p; p = 3]; , + AC_DEFINE(HAVE___UINT32_T_IN_SYS_TYPES_H,1, + [Define 1 if sys/types.h defines __uint32_t.])) + +AC_TRY_COMPILE([ +#include +],[ int p; p = 0; ] , + AC_DEFINE(HAVE_RAW_LIBELF_OK,1, + [Define 1 if plain libelf builds.])) +AC_TRY_COMPILE([ +#define _GNU_SOURCE +#include +],[ off64_t p; p = 0;] , + AC_DEFINE(HAVE_LIBELF_OFF64_OK,1, + [Define 1 if off64 is defined via libelf with GNU_SOURCE.])) + + + +AC_OUTPUT(Makefile) diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwarfdump.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwarfdump.1 Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,144 @@ +.TH DWARFDUMP +.SH NAME +dwarfdump \- dumps DWARF debug information of an ELF object +.SH SYNOPSIS +.B dwarfdump +[-abcdefilmoprsvy] [-t{afv}] [-u\f2objectfile\fP] \f2filename\fP +.SH DESCRIPTION +The +.B dwarfdump +command prints DWARF sections as requested by specific options. +With no options nothing prints! +.PP +The format is intended to be human readable. +If a script is to parse the output, the +.B \-d +option is useful. +.P +Not all sections actually exist in any given object file. +.P +The format may change from release to release, so it is +unwise to depend too heavily on the format. +.P +.PP +Frame information (.debug_frame and .eh_frame) is heavily +dependent on the ABI/ISA of the object file. +The '-R' option uses a built-in 'generic' register name set +handling up to 1000 registers named r0-r999. +The '-x abi=' +flavors below describe how to name an abi and use that to guide +the -f or -F processing. +Without '-R' or '-x abi='/ dwarfdump ignores +the dwarfdump.conf file and uses compiled-in MIPS/IRIX +conventions). +If no '-x name=' is given, dwarfdump +looks for "./dwarfdump.conf", "$HOME/.dwarfdump.conf", "/lib/dwarfdump.conf" and takes the first it finds. +If one or more '-x name=' is given the last of these is +used and all other such files ignored. +.PP +The +.B dwarfdump +command accepts one or more of the following options: +.RS +.TP +.B \-a +Dumps all sections. +Same as +.B \-bcfilmoprsy +.BR \-tfv . +.TP +.B \-b +Dumps the .debug_abbrev section. +.TP +.B \-c +Dumps the .debug_loc section. +.TP +.B \-d +Dense mode. Each die information of the .debug_info section is +printed in one-line format. This option does not imply \fB\-i\fP. +.TP +.B \-e +Ellipsis mode. Short names for DW_TAG_* and DW_ATTR_* are used +in the output for the .debug_info section. +.TP +.B \-f +Dumps the .debug_frame section. +.TP +.B \-i +Dumps the .debug_info section. +.TP +.B \-l +Dumps the .debug_line information. +.TP +.B \-m +Dumps the .debug_macinfo section. +.TP +.B \-o +Dumps the .reloc_debug_* sections. +.TP +.B \-p +Dumps the .debug_pubnames section. +.TP +.B \-r +Dumps the .debug_aranges section. +.TP +.B \-s +Dumps .debug_string section. +.TP +.B \-ta +Same as +.B \-tfv. +.TP +.B \-tf +Dumps the .debug_static_funcs section. +.TP +.B \-tv +Dumps the .debug_static_vars section. +.TP +.BI \-u ofile +Restricts the dumping of sections to the named +compilation unit. +.TP +.B \-v +Verbose mode. Shows more detailed information. +More detailed information about the .debug_frame section prints if +2 or 3 +.B \-v +options are given. +.TP +.B \-w +Dumps the .debug_weaknames section. +.TP +.B \-x abi= +where abi=names an abi in dwarfdump.conf (see the +abiname: command in dwarfdump.conf). +.TP +.B \-x name= +where name=names the full pathname of a dwarfdump configuration +file. Default install location is /usr/local/lib/dwarfdump.conf. +dwarfdump looks first for local ./dwarfdump.conf, then +for $HOME/.dwarfdump.conf then for /usr/local/lib/dwarfdump.conf. +The predefined abi names in dwarfdump.conf are +generic, ia64, m68k, x86, and x86_64. +.TP +.B \-y +Dumps the .debug_types section. +.SH FILES +dwarfdump +./dwarfdump.conf +$(HOME)/.dwarfdump.conf +/lib/dwarfdump.conf +.SH NOTES +In some cases compilers use DW_FORM_data1 (for example) +and in such cases the signedness of the value must be taken +from context. Rather than attempt to determine the +context, dwarfdump prints the value with both signednesses +whenever there is ambiguity about the correct interpretation. +For example, +"DW_AT_const_value 176(as signed = -80)". +For normal DWARF consumers that correctly and fully +evaluate all attributes there is no ambiguity of signedness: +the ambiguity for dwarfdump is due to dwarfdump evaluating +DIEs in a simple order and not keeping track of much context. +.SH BUGS +Support for DWARF3 is being completed but may not be complete. diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwarfdump.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwarfdump.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,763 @@ +/* + Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved. + + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + +$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/dwarfdump.c,v 1.48 2006/04/18 18:05:57 davea Exp $ */ + +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + + +#include "globals.h" + +/* for 'open' */ +#include +#include +#include +#ifdef HAVE_GETOPT_H +#include +#endif + +#include "makename.h" +#include "dwconf.h" +extern char *optarg; + +#define OKAY 0 +#define FAILED 1 +#define BYTES_PER_INSTRUCTION 4 + +static string process_args(int argc, char *argv[]); +static void print_infos(Dwarf_Debug dbg); +static void print_usage_message(void); + +static string program_name; +int check_error = 0; + +/* defined in print_sections.c, die for the current compile unit, + used in get_fde_proc_name() */ +extern Dwarf_Die current_cu_die_for_print_frames; + + +boolean info_flag = FALSE; +boolean use_old_dwarf_loclist = FALSE; /* This so both dwarf_loclist() + and dwarf_loclist_n() can be + tested. Defaults to new + dwarf_loclist_n() */ + +static boolean line_flag = FALSE; +static boolean abbrev_flag = FALSE; +static boolean frame_flag = FALSE; /* .debug_frame section. */ +static boolean eh_frame_flag = FALSE; /* GNU .eh_frame section. */ +static boolean pubnames_flag = FALSE; +static boolean macinfo_flag = FALSE; +static boolean loc_flag = FALSE; +static boolean aranges_flag = FALSE; +static boolean string_flag = FALSE; +static boolean reloc_flag = FALSE; +static boolean static_func_flag = FALSE; +static boolean static_var_flag = FALSE; +static boolean type_flag = FALSE; +static boolean weakname_flag = FALSE; + +int verbose = 0; +boolean dense = FALSE; +boolean ellipsis = FALSE; +boolean dst_format = FALSE; +boolean show_global_offsets = FALSE; + +boolean check_abbrev_code = FALSE; +boolean check_pubname_attr = FALSE; +boolean check_reloc_offset = FALSE; +boolean check_attr_tag = FALSE; +boolean check_tag_tree = FALSE; +boolean check_type_offset = FALSE; +boolean generic_1000_regs = FALSE; + +static boolean dwarf_check = FALSE; + +/* These configure items are for the + frame data. +*/ +static char *config_file_path = 0; +static char *config_file_abi = 0; +static char *config_file_defaults[] = { + "./dwarfdump.conf", + /* Note: HOME location uses .dwarfdump. */ + "HOME/.dwarfdump.conf", +#ifdef CONFPREFIX +/* See Makefile.in "libdir" and CFLAGS */ +/* We need 2 levels of macro to get the name turned into + the string we want. */ +#define STR2(s) # s +#define STR(s) STR2(s) + STR(CONFPREFIX) + "/dwarfdump.conf", +#else + "/usr/lib/dwarfdump.conf", +#endif + 0 +}; +static struct dwconf_s config_file_data; + +char cu_name[BUFSIZ]; +boolean cu_name_flag = FALSE; +Dwarf_Unsigned cu_offset = 0; + +Dwarf_Check_Result abbrev_code_result; +Dwarf_Check_Result pubname_attr_result; +Dwarf_Check_Result reloc_offset_result; +Dwarf_Check_Result attr_tag_result; +Dwarf_Check_Result tag_tree_result; +Dwarf_Check_Result type_offset_result; + +Dwarf_Error err; + +#define PRINT_CHECK_RESULT(str,result) {\ + fprintf(stderr, "%-24s%8d%8d\n", str, result.checks, result.errors); \ +} + +static int process_one_file(Elf * elf, string file_name, int archive, + struct dwconf_s *conf); +static int +open_a_file(string name) +{ + int f = 0; + +#ifdef __CYGWIN__ + f = open(name, O_RDONLY | O_BINARY); +#else + f = open(name, O_RDONLY); +#endif + return f; + +} + +/* + * Iterate through dwarf and print all info. + */ +int +main(int argc, char *argv[]) +{ + string file_name; + int f; + Elf_Cmd cmd; + Elf *arf, *elf; + int archive = 0; + + (void) elf_version(EV_NONE); + if (elf_version(EV_CURRENT) == EV_NONE) { + (void) fprintf(stderr, "dwarfdump: libelf.a out of date.\n"); + exit(1); + } + + file_name = process_args(argc, argv); + f = open_a_file(file_name); + if (f == -1) { + fprintf(stderr, "%s ERROR: can't open %s\n", program_name, + file_name); + return (FAILED); + } + + cmd = ELF_C_READ; + arf = elf_begin(f, cmd, (Elf *) 0); + if (elf_kind(arf) == ELF_K_AR) { + archive = 1; + } + while ((elf = elf_begin(f, cmd, arf)) != 0) { + Elf32_Ehdr *eh32; + +#ifdef HAVE_ELF64_GETEHDR + Elf64_Ehdr *eh64; +#endif /* HAVE_ELF64_GETEHDR */ + eh32 = elf32_getehdr(elf); + if (!eh32) { +#ifdef HAVE_ELF64_GETEHDR + /* not a 32-bit obj */ + eh64 = elf64_getehdr(elf); + if (!eh64) { + /* not a 64-bit obj either! */ + /* dwarfdump is quiet when not an object */ + } else { + process_one_file(elf, file_name, archive, + &config_file_data); + } +#endif /* HAVE_ELF64_GETEHDR */ + } else { + process_one_file(elf, file_name, archive, + &config_file_data); + } + cmd = elf_next(elf); + elf_end(elf); + } + elf_end(arf); + /* Trivial malloc space cleanup. */ + clean_up_die_esb(); + clean_up_syms_malloc_data(); + + if (check_error) + return FAILED; + else + return OKAY; +} + +/* + Given a file which we know is an elf file, process + the dwarf data. + +*/ +static int +process_one_file(Elf * elf, string file_name, int archive, + struct dwconf_s *config_file_data) +{ + Dwarf_Debug dbg; + int dres; + + dres = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &dbg, &err); + if (dres == DW_DLV_NO_ENTRY) { + printf("No DWARF information present in %s\n", file_name); + return 0; + } + if (dres != DW_DLV_OK) { + print_error(dbg, "dwarf_elf_init", dres, err); + } + + if (archive) { + Elf_Arhdr *mem_header = elf_getarhdr(elf); + + printf("\narchive member \t%s\n", + mem_header ? mem_header->ar_name : ""); + } + dwarf_set_frame_rule_inital_value(dbg, + config_file_data-> + cf_initial_rule_value); + dwarf_set_frame_rule_table_size(dbg, + config_file_data-> + cf_table_entry_count); + + if (info_flag || line_flag || cu_name_flag) + print_infos(dbg); + if (pubnames_flag) + print_pubnames(dbg); + if (macinfo_flag) + print_macinfo(dbg); + if (loc_flag) + print_locs(dbg); + if (abbrev_flag) + print_abbrevs(dbg); + if (string_flag) + print_strings(dbg); + if (aranges_flag) + print_aranges(dbg); + if (frame_flag || eh_frame_flag) { + current_cu_die_for_print_frames = 0; + print_frames(dbg, frame_flag, eh_frame_flag, config_file_data); + } + if (static_func_flag) + print_static_funcs(dbg); + if (static_var_flag) + print_static_vars(dbg); + /* DWARF_PUBTYPES is the standard typenames dwarf section. + SGI_TYPENAME is the same concept but is SGI specific ( it was + defined 10 years before dwarf pubtypes). */ + + if (type_flag) { + print_types(dbg, DWARF_PUBTYPES); + print_types(dbg, SGI_TYPENAME); + } + if (weakname_flag) + print_weaknames(dbg); + if (reloc_flag) + print_relocinfo(dbg); + if (dwarf_check) { + fprintf(stderr, "DWARF CHECK RESULT\n"); + fprintf(stderr, " \n"); + } + if (check_pubname_attr) + PRINT_CHECK_RESULT("pubname_attr", pubname_attr_result) + if (check_attr_tag) + PRINT_CHECK_RESULT("attr_tag", attr_tag_result) + if (check_tag_tree) + PRINT_CHECK_RESULT("tag_tree", tag_tree_result) + if (check_type_offset) + PRINT_CHECK_RESULT("type_offset", + type_offset_result) + + dres = dwarf_finish(dbg, &err); + if (dres != DW_DLV_OK) { + print_error(dbg, "dwarf_finish", dres, err); + } + return 0; + +} + +static void do_all() +{ + info_flag = line_flag = frame_flag = abbrev_flag = TRUE; + pubnames_flag = aranges_flag = macinfo_flag = TRUE; + loc_flag = string_flag = TRUE; + reloc_flag = TRUE; + static_func_flag = static_var_flag = TRUE; + type_flag = weakname_flag = TRUE; +} + +/* process arguments and return object filename */ +static string +process_args(int argc, char *argv[]) +{ + extern int optind; + int c = 0; + boolean usage_error = FALSE; + int oarg = 0; + + program_name = argv[0]; + + /* j q unused */ + if (argv[1] != NULL && argv[1][0] != '-') { + do_all(); + } + + while ((c = + getopt(argc, argv, + "abcdefFgGhik:lmoprRst:u:vVwx:yz")) != EOF) { + switch (c) { + case 'x': /* Select abi/path to use */ + { + char *path = 0; + char *abi = 0; + + /* -x name= meaning name dwarfdump.conf file -x + abi= meaning select abi from dwarfdump.conf + file. Must always select abi to use dwarfdump.conf */ + if (strncmp(optarg, "name=", 5) == 0) { + path = makename(&optarg[5]); + if (strlen(path) < 1) + goto badopt; + config_file_path = path; + } else if (strncmp(optarg, "abi=", 4) == 0) { + abi = makename(&optarg[4]); + if (strlen(abi) < 1) + goto badopt; + config_file_abi = abi; + break; + } else { + badopt: + fprintf(stderr, "-x name= \n"); + fprintf(stderr, " and \n"); + fprintf(stderr, "-x abi= \n"); + fprintf(stderr, "are legal, not -x %s\n", optarg); + usage_error = TRUE; + break; + } + } + break; + case 'g': + use_old_dwarf_loclist = TRUE; + /* FALL THROUGH. */ + case 'i': + info_flag = TRUE; + break; + case 'l': + line_flag = TRUE; + break; + case 'f': + frame_flag = TRUE; + break; + case 'F': + eh_frame_flag = TRUE; + break; + case 'b': + abbrev_flag = TRUE; + break; + case 'p': + pubnames_flag = TRUE; + break; + case 'r': + aranges_flag = TRUE; + break; + case 'R': + generic_1000_regs = TRUE; + info_flag = TRUE; + break; + case 'm': + macinfo_flag = TRUE; + break; + case 'c': + loc_flag = TRUE; + break; + case 's': + string_flag = TRUE; + break; + case 'a': + do_all(); + break; + case 'v': + verbose++; + break; + case 'V': + { + printf("%s\n","Version 4May2007"); + } + break; + case 'd': + dense = TRUE; + break; + case 'e': + ellipsis = TRUE; + break; + case 'o': + reloc_flag = TRUE; + break; + case 'k': + dwarf_check = TRUE; + oarg = optarg[0]; + switch (oarg) { + case 'a': + check_pubname_attr = TRUE; + check_attr_tag = TRUE; + check_tag_tree = check_type_offset = TRUE; + pubnames_flag = info_flag = TRUE; + break; + case 'e': + check_pubname_attr = TRUE; + pubnames_flag = TRUE; + break; + case 'r': + check_attr_tag = TRUE; + info_flag = TRUE; + break; + case 't': + check_tag_tree = TRUE; + info_flag = TRUE; + break; + case 'y': + check_type_offset = TRUE; + info_flag = TRUE; + break; + default: + usage_error = TRUE; + break; + } + break; + case 'u': /* compile unit */ + cu_name_flag = TRUE; + strcpy(cu_name, optarg); + break; + case 't': + oarg = optarg[0]; + switch (oarg) { + case 'a': + /* all */ + static_func_flag = static_var_flag = TRUE; + break; + case 'f': + /* .debug_static_func */ + static_func_flag = TRUE; + break; + case 'v': + /* .debug_static_var */ + static_var_flag = TRUE; + break; + default: + usage_error = TRUE; + break; + } + break; + case 'y': /* .debug_types */ + type_flag = TRUE; + break; + case 'w': /* .debug_weaknames */ + weakname_flag = TRUE; + break; + case 'z': + fprintf(stderr, "-z is no longer supported:ignored\n"); + break; + case 'G': + show_global_offsets = TRUE; + break; + default: + usage_error = TRUE; + break; + } + } + + init_conf_file_data(&config_file_data); + if (config_file_abi && generic_1000_regs) { + printf("Specifying both -R and -x abi= is not allowed. Use one " + "or the other. -x abi= ignored.\n"); + config_file_abi = FALSE; + } + if(generic_1000_regs) { + init_generic_config_1000_regs(&config_file_data); + } + if (config_file_abi && (frame_flag || eh_frame_flag)) { + int res = find_conf_file_and_read_config(config_file_path, + config_file_abi, + config_file_defaults, + &config_file_data); + + if (res > 0) { + printf + ("Frame not configured due to error(s). Giving up.\n"); + eh_frame_flag = FALSE; + frame_flag = FALSE; + } + } + if (usage_error || (optind != (argc - 1))) { + print_usage_message(); + exit(FAILED); + } + return argv[optind]; +} + +static void +print_usage_message(void) +{ + fprintf(stderr, "Usage: %s \n", + program_name); + fprintf(stderr, "options:\t-a\tprint all .debug_* sections\n"); + fprintf(stderr, "\t\t-b\tprint abbrev section\n"); + fprintf(stderr, "\t\t-c\tprint loc section\n"); + fprintf(stderr, + "\t\t-d\tdense: one line per entry (info section only)\n"); + fprintf(stderr, + "\t\t-e\tellipsis: short names for tags, attrs etc.\n"); + fprintf(stderr, "\t\t-f\tprint dwarf frame section\n"); + fprintf(stderr, "\t\t-F\tprint gnu .eh_frame section\n"); + fprintf(stderr, "\t\t-g\t(use incomplete loclist support)\n"); + fprintf(stderr, "\t\t-G\tshow global die offsets\n"); + fprintf(stderr, "\t\t-h\tprint exception tables\n"); + fprintf(stderr, "\t\t-i\tprint info section\n"); + fprintf(stderr, "\t\t-k[aerty] check dwarf information\n"); + fprintf(stderr, "\t\t a\tdo all checks\n"); + fprintf(stderr, "\t\t e\texamine attributes of pubnames\n"); + fprintf(stderr, "\t\t r\texamine attr-tag relation\n"); + fprintf(stderr, "\t\t t\texamine tag trees\n"); + fprintf(stderr, "\t\t y\texamine type info\n"); + fprintf(stderr, "\t\t-l\tprint line section\n"); + fprintf(stderr, "\t\t-m\tprint macinfo section\n"); + fprintf(stderr, "\t\t-o\tprint relocation info\n"); + fprintf(stderr, "\t\t-p\tprint pubnames section\n"); + fprintf(stderr, "\t\t-r\tprint aranges section\n"); + fprintf(stderr, "\t\t-R\tPrint frame register names as r33 etc\n"); + fprintf(stderr, "\t\t \t and allow up to 1000 registers.\n"); + fprintf(stderr, "\t\t \t Print using a 'generic' register set.\n"); + fprintf(stderr, "\t\t-s\tprint string section\n"); + fprintf(stderr, "\t\t-t[afv] static: \n"); + fprintf(stderr, "\t\t a\tprint both sections\n"); + fprintf(stderr, "\t\t f\tprint static func section\n"); + fprintf(stderr, "\t\t v\tprint static var section\n"); + fprintf(stderr, + "\t\t-u print sections only for specified file\n"); + fprintf(stderr, "\t\t-v\tverbose: show more information\n"); + fprintf(stderr, "\t\t-vv verbose: show even more information\n"); + fprintf(stderr, "\t\t-V print version information\n"); + fprintf(stderr, "\t\t-x name=\tname dwarfdump.conf\n"); + fprintf(stderr, "\t\t-x abi=\tname abi in dwarfdump.conf\n"); + fprintf(stderr, "\t\t-w\tprint weakname section\n"); + fprintf(stderr, "\t\t-y\tprint type section\n"); + +} + +/* process each compilation unit in .debug_info */ +static void +print_infos(Dwarf_Debug dbg) +{ + Dwarf_Unsigned cu_header_length = 0; + Dwarf_Unsigned abbrev_offset = 0; + Dwarf_Half version_stamp = 0; + Dwarf_Half address_size = 0; + Dwarf_Die cu_die = 0; + Dwarf_Unsigned next_cu_offset = 0; + int nres = DW_DLV_OK; + + if (info_flag) + printf("\n.debug_info\n"); + + /* Loop until it fails. */ + while ((nres = + dwarf_next_cu_header(dbg, &cu_header_length, &version_stamp, + &abbrev_offset, &address_size, + &next_cu_offset, &err)) + == DW_DLV_OK) { + int sres; + + if (cu_name_flag) { + int tres; + Dwarf_Half tag; + Dwarf_Attribute attrib; + Dwarf_Half theform; + int fres; + int ares; + + sres = dwarf_siblingof(dbg, NULL, &cu_die, &err); + if (sres != DW_DLV_OK) { + print_error(dbg, "siblingof cu header", sres, err); + } + tres = dwarf_tag(cu_die, &tag, &err); + if (tres != DW_DLV_OK) { + print_error(dbg, "tag of cu die", tres, err); + } + ares = dwarf_attr(cu_die, DW_AT_name, &attrib, &err); + if (ares != DW_DLV_OK) { + print_error(dbg, "dwarf DW_AT_name ", ares, err); + } + fres = dwarf_whatform(attrib, &theform, &err); + if (fres != DW_DLV_OK) { + print_error(dbg, "dwarf_whatform problem ", fres, err); + } else if (theform == DW_FORM_string + || theform == DW_FORM_strp) { + string temps; + int strres; + string p; + + strres = dwarf_formstring(attrib, &temps, &err); + p = temps; + if (strres != DW_DLV_OK) { + print_error(dbg, + "formstring failed unexpectedly", + strres, err); + } + if (cu_name[0] != '/') { + p = strrchr(temps, '/'); + if (p == NULL) { + p = temps; + } else { + p++; + } + } + if (strcmp(cu_name, p)) { + continue; + } + } else { + print_error(dbg, + "dwarf_whatform unexpected value", + fres, err); + } + dwarf_dealloc(dbg, attrib, DW_DLA_ATTR); + dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); + } + if (verbose) { + if (dense) { + printf("<%s>", "cu_header"); + printf(" %s<%llu>", "cu_header_length", + cu_header_length); + printf(" %s<%d>", "version_stamp", version_stamp); + printf(" %s<%llu>", "abbrev_offset", abbrev_offset); + printf(" %s<%d>\n", "address_size", address_size); + + } else { + printf("\nCU_HEADER:\n"); + printf("\t\t%-28s%llu\n", "cu_header_length", + cu_header_length); + printf("\t\t%-28s%d\n", "version_stamp", version_stamp); + printf("\t\t%-28s%llu\n", "abbrev_offset", + abbrev_offset); + printf("\t\t%-28s%d", "address_size", address_size); + } + } + + /* process a single compilation unit in .debug_info. */ + sres = dwarf_siblingof(dbg, NULL, &cu_die, &err); + if (sres == DW_DLV_OK) { + if (info_flag || cu_name_flag) { + Dwarf_Signed cnt = 0; + char **srcfiles = 0; + int srcf = dwarf_srcfiles(cu_die, + &srcfiles, &cnt, &err); + + if (srcf != DW_DLV_OK) { + srcfiles = 0; + cnt = 0; + } + + print_die_and_children(dbg, cu_die, srcfiles, cnt); + if (srcf == DW_DLV_OK) { + int si; + + for (si = 0; si < cnt; ++si) { + dwarf_dealloc(dbg, srcfiles[si], DW_DLA_STRING); + } + dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST); + } + } + if (line_flag) + print_line_numbers_this_cu(dbg, cu_die); + dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); + } else if (sres == DW_DLV_NO_ENTRY) { + /* do nothing I guess. */ + } else { + print_error(dbg, "Regetting cu_die", sres, err); + } + cu_offset = next_cu_offset; + } + if (nres == DW_DLV_ERROR) { + string errmsg = dwarf_errmsg(err); + Dwarf_Unsigned myerr = dwarf_errno(err); + + fprintf(stderr, "%s ERROR: %s: %s (%lu)\n", + program_name, "attempting to print .debug_info", + errmsg, (unsigned long) myerr); + fprintf(stderr, "attempting to continue.\n"); + } +} + +/* ARGSUSED */ +void +print_error(Dwarf_Debug dbg, string msg, int dwarf_code, + Dwarf_Error err) +{ + fflush(stdout); + fflush(stderr); + if (dwarf_code == DW_DLV_ERROR) { + string errmsg = dwarf_errmsg(err); + Dwarf_Unsigned myerr = dwarf_errno(err); + + fprintf(stderr, "%s ERROR: %s: %s (%lu)\n", + program_name, msg, errmsg, (unsigned long) myerr); + } else if (dwarf_code == DW_DLV_NO_ENTRY) { + fprintf(stderr, "%s NO ENTRY: %s: \n", program_name, msg); + } else if (dwarf_code == DW_DLV_OK) { + fprintf(stderr, "%s: %s \n", program_name, msg); + } else { + fprintf(stderr, "%s InternalError: %s: code %d\n", + program_name, msg, dwarf_code); + } + fflush(stderr); + exit(FAILED); + +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwarfdump.conf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwarfdump.conf Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,415 @@ +# MIPS/IRIX ISA/ABI +# Used to configure dwarfdump printing of .debug_frame and +# .eh_frame. + +# Any number of abi's can be described. Only one can be selected +# in a given darfdump run (see dwarfdump options) +# Available commands are +# beginabi: +# reg: +# frame_interface: +# cfa_reg: +# initial_reg_value: +# reg_table_size: +# endabi: +# +# Symbolic names do not work here, use literal numbers +# where applicable (in C standard decimal, octal (leading 0) or +# hexadecimal ). +# +# Whitespace is required to separate command: from operands and +# operands from each other on a line. +# +# There is no ordering required within a beginabi/endabi pair. +# As many ABIs as required may be listed. +# dwarfdump will choose exactly one abi to dump frame information. +# + + +# Here using MIPS abi as an example to describe +# the format. The MIPS/IRIX ABI is built-in to dwarfdump, so this one +# is not really required. +# Begin with abi name (use here and on dwarfdump command line). +beginabi: mips + +# Instructs dwarfdump to default to the older frame interface. +# Use value 3 to use the newer interface. +# The '2' interface is supported but deprecated (deprecated +# because it cannot work with all popular ABIs: mixing +# the cfa-rule into the table column set was not a good idea +# but it is part of the MIPS/IRIX standard usage). +frame_interface: 2 + +# If (and only if) using frame_interface: 2 tell dwarfdump +# what table colum that DW_FRAME_CFA_COL is. +# If using frame_interface: 3 cfa_reg: should be +# DW_FRAME_CFA_COL3 (1036) +cfa_reg: 0 + +# For MIPS, the same as DW_FRAME_SAME_VAL (1035). +# For other ISA/ABIs 1034 (DW_FRAME_UNDEFINED_VAL) might be better. +# Depends on the ABI convention, if set wrong way too many +# regs will be listed in the frame output. +# This instructs dwarfdump to set libdwarf to this value, +# overriding the libdwarf default. +# If initial_reg_value not set the libdwarf default is used +# (see libdwarf.h DW_FRAME_REG_INITIAL_VALUE). +initial_reg_value: 1035 # DW_FRAME_SAME_VAL + +# Built in to frame_interface: 2 as 66. +reg_table_size: 66 + + +# Only name registers for wich a r4 (for example) is not what you +# want to see +# No particular order of the reg: lines required. +reg: cfa 0 # Used with MIPS/IRIX original DWARF2 interface +reg: r1/at 1 +reg: r2/v0 2 +reg: r3/v1 3 +reg: r4/a0 4 +reg: r5/a1 5 +reg: r6/a2 6 +reg: r7/a3 7 +reg: r8/t0 8 +reg: r9/t1 9 +reg: r10/t2 10 +reg: r11/t3 11 +reg: r12/t4 12 +reg: r13/t5 13 +reg: r14/t6 14 +reg: r15/t7 15 +reg: r16/s0 16 +reg: r17/s1 17 +reg: r18/s2 18 +reg: r19/s3 19 +reg: r20/s4 20 +reg: r21/s5 21 +reg: r22/s6 22 +reg: r23/s7 23 +reg: r24/t8 24 +reg: r25/t9 25 +reg: r26/k0 26 +reg: r27/k1 27 +reg: r28/gp 28 +reg: r29/sp 29 +reg: r30/s8 30 +reg: r31 31 + +reg: $f0 32 +reg: $f1 33 +reg: $f2 34 +reg: $f3 35 +reg: $f4 36 +reg: $f5 37 +reg: $f6 38 +reg: $f7 39 +reg: $f8 40 +reg: $f9 41 +reg: $f10 42 +reg: $f11 43 +reg: $f12 44 +reg: $f13 45 +reg: $f14 46 +reg: $f15 47 +reg: $f16 48 +reg: $f17 49 +reg: $f18 50 +reg: $f19 51 +reg: $f20 52 +reg: $f21 53 +reg: $f22 54 +reg: $f23 55 +reg: $f24 56 +reg: $f25 57 +reg: $f26 58 +reg: $f27 59 +reg: $f28 60 +reg: $f29 61 +reg: $f30 62 +reg: $f31 63 +reg: ra 64 +reg: slk 65 + + +# End of abi definition. +endabi: mips + + + + + + +# MIPS/IRIX ISA/ABI for testing libdwarf. +beginabi: mips-simple +frame_interface: 2 +reg_table_size: 66 +cfa_reg: 0 +initial_reg_value: 1035 + +reg: cfa 0 # Used with MIPS/IRIX original DWARF2 interface +reg: ra 64 +reg: slk 65 + +# End of abi definition. +endabi: mips-simple + +# MIPS/IRIX ISA/ABI for testing the new frame interface +# with libdwarf. +beginabi: mips-simple3 +frame_interface: 3 + +# When using frame_interface: 3 the size of the register table +# is not fixed. It can be as large as needed. +reg_table_size: 66 +cfa_reg: 1036 # DW_FRAME_CFA_COL3 +initial_reg_value: 1035 + +# No cfa as a 'normal' register. +# Rule 0 is just register 0, which is not used +# in frame descriptions. +# (so cfa does not have a number here, and dwarfdump gives +# it the name 'cfa' automatically). +reg: ra 64 +reg: slk 65 +# End of abi definition. +endabi: mips-simple3 + + +beginabi: ia64 +frame_interface: 3 +initial_reg_value: 1034 # DW_FRAME_UNDEFINED_VAL +cfa_reg: 1036 # DW_FRAME_CFA_COL3 +reg_table_size: 695 + +# The following register names are not necessarily correct... +# Register indexes r32-r127 not used. +reg: f0 128 +# ... +reg: f127 255 +reg: b0 321 +reg: b1 322 +reg: b2 323 +reg: b3 324 +reg: b4 325 +reg: b5 326 +reg: b6 327 +reg: b7 328 +reg: vfp 329 +reg: vrap 330 +reg: pr 331 +reg: ip 332 +reg: psr 333 +reg: cfm 334 +reg: k0 335 +reg: k1 336 +reg: k2 337 +reg: k3 338 +reg: k4 339 +reg: k5 340 +reg: k6 341 +reg: k7 342 +reg: rsc 350 +reg: bsp 351 +reg: bspstore 352 +reg: rnat 353 +reg: fcr 355 +reg: eflag 358 +reg: csd 359 +reg: ssd 360 +reg: cflg 361 +reg: fsr 362 +reg: fir 363 +reg: fdr 364 +reg: pfs 398 +reg: lc 399 +reg: ec 400 + +endabi: ia64 + + +beginabi: x86 +frame_interface: 3 +initial_reg_value: 1035 # DW_FRAME_SAME_VAL +reg_table_size: 66 # more than large enough, hopefully. +cfa_reg: 1036 # DW_FRAME_CFA_COL3 + +# The following register names are not necessarily correct... +reg: eax 0 +reg: ecx 1 +reg: edx 2 +reg: ebx 3 +reg: esp 4 +reg: ebp 5 +reg: esi 6 +reg: edi 7 +reg: eip 8 +reg: eflags 9 + +reg: trapno 10 +reg: st0 11 +reg: st1 12 +reg: st2 13 +reg: st3 14 +reg: st4 15 +reg: st5 16 +reg: st6 17 +reg: st7 18 +# 19 is ? 20 is ? +reg: xmm0 21 +reg: xmm1 22 +reg: xmm2 23 +reg: xmm3 24 +reg: xmm4 25 +reg: xmm5 26 +reg: xmm6 27 +reg: xmm7 28 + +reg: mm0 29 +reg: mm1 30 +reg: mm2 31 +reg: mm3 32 +reg: mm4 33 +reg: mm5 34 +reg: mm6 35 +reg: mm7 36 + +reg: fcw 37 +reg: fsw 38 +reg: mxcsr 39 + +reg: es 40 +reg: cs 41 +reg: ss 42 +reg: ds 43 +reg: fs 44 +reg: gs 45 +# 46 47 are ? +reg: tr 48 +reg: ldtr 49 + + +endabi: x86 + + +beginabi: x86_64 +frame_interface: 3 +initial_reg_value: 1035 # DW_FRAME_SAME_VAL +reg_table_size: 66 # more than large enough, hopefully. +cfa_reg: 1036 # DW_FRAME_CFA_COL3 + +# The following register names are not necessarily correct... +reg: rax 0 +reg: rdx 1 +reg: rcx 2 +reg: rbx 3 +reg: rsi 4 +reg: rdi 5 +reg: rbp 6 +reg: rsp 7 +reg: r8 8 +reg: r9 9 +reg: r10 10 +reg: r11 11 +reg: r12 12 +reg: r13 13 +reg: r14 14 +reg: r15 15 +reg: rip 16 +reg: xmm0 17 +reg: xmm1 18 +reg: xmm2 19 +reg: xmm3 20 +reg: xmm4 21 +reg: xmm5 22 +reg: xmm6 23 +reg: xmm7 24 +reg: xmm8 25 +reg: xmm9 26 +reg: xmm10 27 +reg: xmm11 28 +reg: xmm12 29 +reg: xmm13 30 +reg: xmm14 31 +reg: xmm15 32 + +reg: st0 33 +reg: st1 34 +reg: st2 35 +reg: st3 36 +reg: st4 37 +reg: st5 38 +reg: st6 39 +reg: st7 40 + +reg: mm0 41 +reg: mm1 42 +reg: mm2 43 +reg: mm3 44 +reg: mm4 45 +reg: mm5 46 +reg: mm6 47 +reg: mm7 48 + +reg: rflags 49 +reg: es 50 +reg: cs 51 +reg: ss 52 +reg: ds 53 +reg: fs 54 +reg: gs 55 +# 56, 57 are ? +reg: fs.base 58 +reg: gs.base 59 +# 60 61 are ? +reg: tr 62 +reg: ldtr 63 + +endabi: x86_64 + +beginabi: m68k +frame_interface: 3 +initial_reg_value: 1035 # DW_FRAME_SAME_VAL +reg_table_size: 66 # more than large enough, hopefully. +cfa_reg: 1036 # DW_FRAME_CFA_COL3 + +reg: d0 0 +reg: d1 1 +reg: d2 2 +reg: d3 3 +reg: d4 4 +reg: d5 5 +reg: d6 6 +reg: d7 7 + +reg: a0 8 +reg: a1 9 +reg: a2 10 +reg: a3 11 +reg: a4 12 +reg: a5 13 +reg: a6 14 +reg: sp 15 + +reg: fp0 16 +reg: fp1 17 +reg: fp2 18 +reg: fp3 19 +reg: fp4 20 +reg: fp5 21 +reg: fp6 22 +reg: pc 23 + +endabi: m68k + +# 'Generic 1000 register abi'. +# This is useful as a 'general' ABI settings for +# cpus using up to 1000 registers. The register names +# show as a number, like 'r991'. +beginabi: generic +frame_interface: 3 +initial_reg_value: 1035 # DW_FRAME_SAME_VAL +cfa_reg: 1036 # DW_FRAME_CFA_COL3 +reg_table_size: 1000 +reg: r0 0 +endabi: generic diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwconf.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwconf.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1142 @@ +/* + Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + +$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/dwconf.c,v 1.4 2006/04/18 18:05:57 davea Exp $ */ + + +#include "globals.h" +#include +#include "dwconf.h" +#include "makename.h" + + +struct token_s { + unsigned tk_len; + char *tk_data; +}; +enum linetype_e { + LT_ERROR, + LT_COMMENT, + LT_BLANK, + LT_BEGINABI, + LT_REG, + LT_FRAME_INTERFACE, + LT_CFA_REG, + LT_INITIAL_REG_VALUE, + LT_REG_TABLE_SIZE, + LT_ENDABI +}; + +struct comtable_s { + enum linetype_e type; + char *name; + size_t namelen; +}; + +static int errcount = 0; /* Count errors found in this scan of + the configuration file. */ + +static char name_begin_abi[] = "beginabi:"; +static char name_reg[] = "reg:"; +static char name_frame_interface[] = "frame_interface:"; +static char name_cfa_reg[] = "cfa_reg:"; +static char name_initial_reg_value[] = "initial_reg_value:"; +static char name_reg_table_size[] = "reg_table_size:"; +static char name_endabi[] = "endabi:"; + +static struct comtable_s comtable[] = { + {LT_BEGINABI, name_begin_abi}, + {LT_REG, name_reg}, + {LT_FRAME_INTERFACE, name_frame_interface}, + {LT_CFA_REG, name_cfa_reg}, + {LT_INITIAL_REG_VALUE, name_initial_reg_value}, + {LT_REG_TABLE_SIZE, name_reg_table_size}, + {LT_ENDABI, name_endabi}, +}; +static int size_of_comtable = sizeof(comtable) / sizeof(comtable[0]); + + +static FILE *find_a_file(char *named_file, char **defaults, + string * name_used); +static int find_abi_start(FILE * stream, char *abi_name, long *offset, + unsigned long *lineno_out); +static int parse_abi(FILE * stream, char *fname, char *abiname, + struct dwconf_s *out, unsigned long lineno); +static char *get_token(char *cp, struct token_s *outtok); + + + + + +/* This finds a dwarfdump.conf file and + then parses it. It updates + conf_out as appropriate. + + This finds the first file (looking in a set of places) + with that name. It then looks for the right ABI entry. + If the first file it finds does not have that ABI entry it + gives up. + + It would also be reasonable to search every 'dwarfdump.conf' + it finds for the abi. But we stop at the first dwarfdump.conf + we find. +*/ +int +find_conf_file_and_read_config(char *named_file, + char *named_abi, char **defaults, + struct dwconf_s *conf_out) +{ + + FILE *conf_stream = 0; + char *name_used = 0; + long offset = 0; + int res = FALSE; + unsigned long lineno = 0; + + errcount = 0; + + conf_stream = find_a_file(named_file, defaults, &name_used); + if (!conf_stream) { + ++errcount; + printf("dwarfdump found no file %s!\n", + named_file ? named_file : "readable for configuration. " + "(add options -v -v to see what file names tried)\n"); + return errcount; + } + if (verbose > 1) { + printf("dwarfdump using configuration file %s\n", name_used); + } + + res = find_abi_start(conf_stream, named_abi, &offset, &lineno); + if (errcount > 0) { + ++errcount; + printf("dwarfdump found no ABI %s in file %s.\n", + named_abi, name_used); + return errcount; + } + res = fseek(conf_stream, offset, SEEK_SET); + if (res != 0) { + ++errcount; + printf("dwarfdump seek to %ld offset in %s failed!\n", + offset, name_used); + return errcount; + } + parse_abi(conf_stream, name_used, named_abi, conf_out, lineno); + fclose(conf_stream); + return errcount; +} + +/* Given path strings, attempt to make a canonical file name: + that is, avoid superfluous '/' so that no + '//' (or worse) is created in the output. The path components + are to be separated so at least one '/' + is to appear between the two 'input strings' when + creating the output. +*/ +static char * +canonical_append(char *target, unsigned int target_size, + char *first_string, char *second_string) +{ + size_t firstlen = strlen(first_string); + + /* +1 +1: Leave room for added "/" and final NUL, though that is + overkill, as we drop a NUL byte too. */ + if ((firstlen + strlen(second_string) + 1 + 1) >= target_size) { + /* Not enough space. */ + return NULL; + } + for (; *second_string == '/'; ++second_string) { + } + for (; firstlen > 0 && first_string[firstlen - 1] == '/'; + --firstlen) { + } + target[0] = 0; + if (firstlen > 0) { + strncpy(target, first_string, firstlen); + target[firstlen + 1] = 0; + } + target[firstlen] = '/'; + firstlen++; + target[firstlen] = 0; + strcat(target, second_string); + return target; +} + +#ifdef BUILD_FOR_TEST +#define CANBUF 25 +struct canap_s { + char *res_exp; + char *first; + char *second; +} canap[] = { + { + "ab/c", "ab", "c"}, { + "ab/c", "ab/", "c"}, { + "ab/c", "ab", "/c"}, { + "ab/c", "ab////", "/////c"}, { + "ab/", "ab", ""}, { + "ab/", "ab////", ""}, { + "ab/", "ab////", ""}, { + "/a", "", "a"}, { + 0, "/abcdefgbijkl", "pqrstuvwxyzabcd"}, { + 0, 0, 0} +}; +static void +test_canonical_append(void) +{ + /* Make buf big, this is test code, so be safe. */ + char lbuf[1000]; + unsigned i; + unsigned failcount = 0; + + printf("Entry test_canonical_append\n"); + for (i = 0;; ++i) { + char *res = 0; + + if (canap[i].first == 0 && canap[i].second == 0) + break; + + res = canonical_append(lbuf, CANBUF, canap[i].first, + canap[i].second); + if (res == 0) { + if (canap[i].res_exp == 0) { + /* GOOD */ + printf("PASS %u\n", i); + } else { + ++failcount; + printf("FAIL: entry %u wrong, expected %s, got NULL\n", + i, canap[i].res_exp); + } + } else { + if (canap[i].res_exp == 0) { + ++failcount; + printf("FAIL: entry %u wrong, got %s expected NULL\n", + i, res); + } else { + if (strcmp(res, canap[i].res_exp) == 0) { + printf("PASS %u\n", i); + /* GOOD */ + } else { + ++failcount; + printf("FAIL: entry %u wrong, expected %s got %s\n", + i, canap[i].res_exp, res); + } + } + } + } + printf("FAIL count %u\n", failcount); + +} +#endif /* BUILD_FOR_TEST */ +/* Try to find a file as named and open for read. + We treat each name as a full name, we are not + combining separate name and path components. + This is an arbitrary choice... + + The defaults are listed in dwarfdump.c in the array + config_file_defaults[]. +*/ +static FILE * +find_a_file(char *named_file, char **defaults, string * name_used) +{ + FILE *fin = 0; + char *lname = named_file; + const char *type = "rw"; + int i = 0; + +#ifdef BUILD_FOR_TEST + test_canonical_append(); +#endif /* BUILD_FOR_TEST */ + + if (lname) { + /* Name given, just assume it is fully correct, try no other. */ + if (verbose > 1) { + printf("dwarfdump looking for configuration as %s\n", + lname); + } + fin = fopen(lname, type); + if (fin) { + *name_used = lname; + return fin; + } + return 0; + } + /* No name given, find a default, if we can. */ + for (i = 0; defaults[i]; ++i) { + lname = defaults[i]; + if (strncmp(lname, "HOME/", 5) == 0) { + /* arbitrary size */ + char buf[2000]; + char *homedir = getenv("HOME"); + + if (homedir) { + char *cp = canonical_append(buf, sizeof(buf), + homedir, lname + 5); + + if (!cp) { + /* OOps, ignore this one. */ + continue; + } + lname = makename(buf); + } + } + if (verbose > 1) { + printf("dwarfdump looking for configuration as %s\n", + lname); + } + fin = fopen(lname, type); + if (fin) { + *name_used = lname; + return fin; + } + } + return 0; +} + +/* Start at a token begin, see how long it is, + return length. */ +unsigned +find_token_len(char *cp) +{ + unsigned len = 0; + + for (; *cp; ++cp) { + if (isspace(*cp)) { + return len; + } + if (*cp == '#') { + return len; /* begins comment */ + } + ++len; + } + return len; +} + +/* + Skip past all whitespace: the only code that even knows + what whitespace is. +*/ +static char * +skipwhite(char *cp) +{ + for (; *cp; ++cp) { + if (!isspace(*cp)) { + return cp; + } + } + return cp; +} + +/* Return TRUE if ok. FALSE if find more tokens. + Emit error message if error. +*/ +static int +ensure_has_no_more_tokens(char *cp, char *fname, unsigned long lineno) +{ + struct token_s tok; + + cp = get_token(cp, &tok); + if (tok.tk_len > 0) { + printf("dwarfdump.conf error: " + "extra characters after command operands, found " + "\"%s\" in %s line %lu\n", tok.tk_data, fname, lineno); + ++errcount; + return FALSE; + } + return TRUE; +} + + +/* + There may be many beginabi: lines in a dwarfdump.conf file, + find the one we want and return it's file offset. +*/ +static int +find_abi_start(FILE * stream, + char *abi_name, long *offset, unsigned long *lineno_out) +{ + char buf[100]; + unsigned long lineno = 0; + + for (; !feof(stream);) { + + struct token_s tok; + char *line = 0; + long loffset = ftell(stream); + + line = fgets(buf, sizeof(buf), stream); + ++lineno; + if (!line) { + ++errcount; + return FALSE; + } + + line = get_token(buf, &tok); + + if (strcmp(tok.tk_data, name_begin_abi) != 0) { + continue; + } + get_token(line, &tok); + if (strcmp(tok.tk_data, abi_name) != 0) { + continue; + } + + *offset = loffset; + *lineno_out = lineno; + return TRUE; + } + + ++errcount; + return FALSE; +} + +static char *tempstr = 0; +static unsigned tempstr_len = 0; + +/* + Use a global buffer (tempstr) to turn a non-delimited + input char array into a NUL-terminated C string + (with the help of makename() to get a permanent + address for the result ing string). +*/ +static char * +build_string(unsigned tlen, char *cp) +{ + if (tlen >= tempstr_len) { + free(tempstr); + tempstr = malloc(tlen + 100); + } + strncpy(tempstr, cp, tlen); + tempstr[tlen] = 0; + return makename(tempstr); +} + +/* + The tokenizer for our simple parser. +*/ +static char * +get_token(char *cp, struct token_s *outtok) +{ + char *lcp = skipwhite(cp); + unsigned tlen = find_token_len(lcp); + + outtok->tk_len = tlen; + if (tlen > 0) { + outtok->tk_data = build_string(tlen, lcp); + } else { + outtok->tk_data = ""; + } + return lcp + tlen; + +} + +/* + We can't get all the field set up statically very easily, + so we get the command string length set here. +*/ +static void +finish_comtable_setup(void) +{ + unsigned i; + + for (i = 0; i < size_of_comtable; ++i) { + comtable[i].namelen = strlen(comtable[i].name); + } +} + +/* + Given a line of the table, determine if it is a command + or not, and if a command, which one is it. + Return LT_ERROR if it's not recognized. +*/ +static enum linetype_e +which_command(char *cp, struct comtable_s **tableentry) +{ + int i; + struct token_s tok; + + if (*cp == '#') + return LT_COMMENT; + if (!*cp) + return LT_BLANK; + + get_token(cp, &tok); + + for (i = 0; i < size_of_comtable; ++i) { + if (tok.tk_len == comtable[i].namelen && + strcmp(comtable[i].name, tok.tk_data) == 0) { + + *tableentry = &comtable[i]; + return comtable[i].type; + } + } + + return LT_ERROR; +} + +/* We are promised it's an abiname: command + find the name on the line. +*/ +static int +parsebeginabi(char *cp, char *fname, char *abiname, + unsigned long lineno, struct comtable_s *comtab) +{ + size_t clen = comtab->namelen; + size_t abinamelen = strlen(abiname); + struct token_s tok; + + + cp = cp + clen + 1; + cp = skipwhite(cp); + get_token(cp, &tok); + if (tok.tk_len != abinamelen || + strncmp(cp, abiname, abinamelen) != 0) { + printf("dwarfdump internal error: " + "mismatch %s with %s %s line %lu\n", + cp, tok.tk_data, fname, lineno); + ++errcount; + return FALSE; + } + { + int res = + ensure_has_no_more_tokens(cp + tok.tk_len, fname, lineno); + return res; + } +} + +/* This expands register names as required, but does not + ensure no names duplicated. +*/ +#define CONF_TABLE_OVERSIZE 100 +static void +add_to_reg_table(struct dwconf_s *conf, + char *rname, unsigned long rval, char *fname, + unsigned long lineno) +{ + if (conf->cf_regs_malloced == 0) { + conf->cf_regs = 0; + conf->cf_named_regs_table_size = 0; + } + if (rval >= conf->cf_named_regs_table_size) { + char **newregs = 0; + unsigned long newtablen = rval + CONF_TABLE_OVERSIZE; + unsigned long newtabsize = newtablen * sizeof(char *); + unsigned long oldtabsize = + conf->cf_named_regs_table_size * sizeof(char *); + newregs = realloc(conf->cf_regs, newtabsize); + if (!newregs) { + printf("dwarfdump: unable to malloc table %lu bytes. " + " %s line %lu\n", newtabsize, fname, lineno); + exit(1); + } + /* Zero out the new entries. */ + memset((char *) newregs + (oldtabsize), 0, + (newtabsize - oldtabsize)); + conf->cf_named_regs_table_size = (unsigned long) newtablen; + conf->cf_regs = newregs; + conf->cf_regs_malloced = 1; + } + conf->cf_regs[rval] = rname; + return; +} + +/* Our input is supposed to be a number. + Determine the value (and return it) or generate an error message. +*/ +static int +make_a_number(char *cmd, char *filename, unsigned long + lineno, struct token_s *tok, unsigned long *val_out) +{ + char *endnum = 0; + unsigned long val = 0; + + val = strtoul(tok->tk_data, &endnum, 0); + if (val == 0 && endnum == (tok->tk_data)) { + printf("dwarfdump.conf error: " + "%s missing register number (\"%s\" not valid) %s line %lu", + cmd, tok->tk_data, filename, lineno); + ++errcount; + return FALSE; + } + if (endnum != (tok->tk_data + tok->tk_len)) { + printf("dwarfdump.conf error: " + "%s Missing register number (\"%s\" not valid) %s line %lu", + cmd, tok->tk_data, filename, lineno); + ++errcount; + return FALSE; + } + *val_out = val; + return TRUE; + + + +} + +/* We are guaranteed it's a reg: command, so parse that command + and record the interesting data. +*/ +static int +parsereg(char *cp, char *fname, unsigned long lineno, + struct dwconf_s *conf, struct comtable_s *comtab) +{ + size_t clen = comtab->namelen; + struct token_s regnum; + struct token_s tokreg; + unsigned long val = 0; + int ok = FALSE; + + cp = cp + clen + 1; + cp = get_token(cp, &tokreg); + cp = get_token(cp, ®num); + if (tokreg.tk_len == 0) { + printf("dwarfdump.conf error: " + "reg: missing register name %s line %lu", + fname, lineno); + ++errcount; + return FALSE; + + } + if (regnum.tk_len == 0) { + printf("dwarfdump.conf error: " + "reg: missing register number %s line %lu", + fname, lineno); + ++errcount; + return FALSE; + } + + ok = make_a_number(comtab->name, fname, lineno, ®num, &val); + + if (!ok) { + ++errcount; + return FALSE; + } + + add_to_reg_table(conf, tokreg.tk_data, val, fname, lineno); + + { + int res = ensure_has_no_more_tokens(cp, fname, lineno); + + return res; + } +} + +/* + We are guaranteed it's an frame_interface: command. + Parse it and record the value data. +*/ +static int +parseframe_interface(char *cp, char *fname, unsigned long lineno, + struct dwconf_s *conf, struct comtable_s *comtab) +{ + size_t clen = comtab->namelen; + struct token_s tok; + unsigned long val = 0; + int ok = FALSE; + + cp = cp + clen + 1; + cp = get_token(cp, &tok); + if (tok.tk_len == 0) { + printf("dwarfdump.conf error: " + "%s missing interface number %s line %lu", + comtab->name, fname, lineno); + ++errcount; + return FALSE; + } + + ok = make_a_number(comtab->name, fname, lineno, &tok, &val); + + if (!ok) { + ++errcount; + return FALSE; + } + if (val != 2 && val != 3) { + printf("dwarfdump.conf error: " + "%s only interface numbers 2 or 3 are allowed, " + " not %lu. %s line %lu", + comtab->name, val, fname, lineno); + ++errcount; + return FALSE; + } + + conf->cf_interface_number = (int) val; + { + int res = ensure_has_no_more_tokens(cp, fname, lineno); + + return res; + } +} + +/* + We are guaranteed it's a cfa_reg: command. Parse it + and record the important data. +*/ +static int +parsecfa_reg(char *cp, char *fname, unsigned long lineno, + struct dwconf_s *conf, struct comtable_s *comtab) +{ + size_t clen = comtab->namelen; + struct token_s tok; + unsigned long val = 0; + int ok = FALSE; + + cp = cp + clen + 1; + cp = get_token(cp, &tok); + if (tok.tk_len == 0) { + printf("dwarfdump.conf error: " + "%s missing cfa_reg number %s line %lu", + comtab->name, fname, lineno); + ++errcount; + return FALSE; + } + + ok = make_a_number(comtab->name, fname, lineno, &tok, &val); + + if (!ok) { + ++errcount; + return FALSE; + } + conf->cf_cfa_reg = (int) val; + { + int res = ensure_has_no_more_tokens(cp, fname, lineno); + + return res; + } +} + + +/* We are guaranteed it's an initial_reg_value: command, + parse it and put the reg value where it will be remembered. +*/ +static int +parseinitial_reg_value(char *cp, char *fname, + unsigned long lineno, + struct dwconf_s *conf, struct comtable_s *comtab) +{ + size_t clen = comtab->namelen; + struct token_s tok; + unsigned long val = 0; + int ok = FALSE; + + cp = cp + clen + 1; + cp = get_token(cp, &tok); + if (tok.tk_len == 0) { + printf("dwarfdump.conf error: " + "%s missing initial reg value %s line %lu", + comtab->name, fname, lineno); + ++errcount; + return FALSE; + } + + ok = make_a_number(comtab->name, fname, lineno, &tok, &val); + + if (!ok) { + + ++errcount; + return FALSE; + } + conf->cf_initial_rule_value = (int) val; + { + int res = ensure_has_no_more_tokens(cp, fname, lineno); + + return res; + } +} + + +/* We are guaranteed it's a table size command, parse it + and record the table size. +*/ +static int +parsereg_table_size(char *cp, char *fname, unsigned long lineno, + struct dwconf_s *conf, struct comtable_s *comtab) +{ + size_t clen = comtab->namelen; + struct token_s tok; + unsigned long val = 0; + int ok = FALSE; + + cp = cp + clen + 1; + cp = get_token(cp, &tok); + if (tok.tk_len == 0) { + printf("dwarfdump.conf error: " + "%s missing reg table size value %s line %lu", + comtab->name, fname, lineno); + ++errcount; + return FALSE; + } + + ok = make_a_number(comtab->name, fname, lineno, &tok, &val); + + if (!ok) { + ++errcount; + return FALSE; + } + conf->cf_table_entry_count = (unsigned long) val; + { + int res = ensure_has_no_more_tokens(cp, fname, lineno); + + return res; + } + +} + + +/* We are guaranteed it's an endabi: command, parse it and + check we have the right abi. +*/ +static int +parseendabi(char *cp, char *fname, char *abiname, unsigned long lineno, + struct comtable_s *comtab) +{ + size_t clen = comtab->namelen; + struct token_s tok; + + + cp = cp + clen + 1; + cp = get_token(cp, &tok); + if (strcmp(abiname, tok.tk_data) != 0) { + printf("%s error: " + "mismatch abi name %s (here) vs. %s (beginabi:) %s line %lu\n", + comtab->name, tok.tk_data, abiname, fname, lineno); + ++errcount; + return FALSE; + } + { + int res = ensure_has_no_more_tokens(cp, fname, lineno); + + return res; + } + +} + + + +/* Return TRUE if we succeeded and filed in *out. + Return FALSE if we failed (and fill in nothing). + beginabi: + reg: + frame_interface: + cfa_reg: + initial_reg_value: + reg_table_size: + endabi: + + We are positioned at the start of a beginabi: line when + called. + +*/ +static int +parse_abi(FILE * stream, char *fname, char *abiname, + struct dwconf_s *out, unsigned long lineno) +{ + struct dwconf_s localconf; + char buf[1000]; + int comtype = 0; + long regcount = 0; + + unsigned long beginabi_lineno = 0; + unsigned long frame_interface_lineno = 0; + unsigned long initial_reg_value_lineno = 0; + unsigned long reg_table_size_lineno = 0; + unsigned long cfa_reg_lineno = 0; + static int first_time_done = 0; + struct comtable_s *comtabp = 0; + + + if (first_time_done == 0) { + finish_comtable_setup(); + first_time_done = 1; + } + + + + + init_conf_file_data(&localconf); + + for (; !feof(stream);) { + + char *line = 0; + + /* long loffset = ftell(stream); */ + line = fgets(buf, sizeof(buf), stream); + if (!line) { + ++errcount; + printf + ("dwarfdump: end of file or error before endabi: in %s, line %lu\n", + fname, lineno); + return FALSE; + } + ++lineno; + line = skipwhite(line); + comtype = which_command(line, &comtabp); + switch (comtype) { + case LT_ERROR: + ++errcount; + printf + ("dwarfdump: Unknown text in %s is \"%s\" at line %lu\n", + fname, line, lineno); + break; + case LT_COMMENT: + break; + case LT_BLANK: + break; + case LT_BEGINABI: + if (beginabi_lineno > 0) { + ++errcount; + printf + ("dwarfdump: Encountered beginabi: when not expected. " + "%s line %lu previous beginabi line %lu\n", fname, + lineno, beginabi_lineno); + } + beginabi_lineno = lineno; + parsebeginabi(line, fname, abiname, lineno, comtabp); + break; + + case LT_REG: + parsereg(line, fname, lineno, &localconf, comtabp); + ++regcount; + break; + case LT_FRAME_INTERFACE: + if (frame_interface_lineno > 0) { + ++errcount; + printf + ("dwarfdump: Encountered duplicate frame_interface: " + "%s line %lu previous frame_interface: line %lu\n", + fname, lineno, frame_interface_lineno); + } + frame_interface_lineno = lineno; + parseframe_interface(line, fname, + lineno, &localconf, comtabp); + break; + case LT_CFA_REG: + if (cfa_reg_lineno > 0) { + printf("dwarfdump: Encountered duplicate cfa_reg: " + "%s line %lu previous cfa_reg line %lu\n", + fname, lineno, cfa_reg_lineno); + ++errcount; + } + cfa_reg_lineno = lineno; + parsecfa_reg(line, fname, lineno, &localconf, comtabp); + break; + case LT_INITIAL_REG_VALUE: + if (initial_reg_value_lineno > 0) { + printf + ("dwarfdump: Encountered duplicate initial_reg_value_lineno: " + "%s line %lu previous initial_reg_value: line %lu\n", + fname, lineno, initial_reg_value_lineno); + ++errcount; + } + initial_reg_value_lineno = lineno; + + parseinitial_reg_value(line, fname, + lineno, &localconf, comtabp); + break; + case LT_REG_TABLE_SIZE: + if (reg_table_size_lineno > 0) { + printf("dwarfdump: duplicate reg_table_size: " + "%s line %lu previous reg_table_size: line %lu\n", + fname, lineno, reg_table_size_lineno); + ++errcount; + } + reg_table_size_lineno = lineno; + parsereg_table_size(line, fname, + lineno, &localconf, comtabp); + break; + case LT_ENDABI: + parseendabi(line, fname, abiname, lineno, comtabp); + + if (regcount > localconf.cf_table_entry_count) { + printf("dwarfdump: more registers named than " + " in %s ( %lu named vs %s %lu) %s line %lu\n", + abiname, (unsigned long) regcount, + name_reg_table_size, + (unsigned long) localconf.cf_table_entry_count, + fname, (unsigned long) lineno); + ++errcount; + } + + *out = localconf; + return TRUE; + default: + printf + ("dwarfdump internal error, impossible line type %d %s %lu \n", + (int) comtype, fname, lineno); + exit(1); + + } + } + ++errcount; + printf("End of file, no endabi: found. %s, line %lu\n", + fname, lineno); + return FALSE; +} + +/* MIPS/IRIX frame register names. + For alternate name sets, use dwarfdump.conf or + revise dwarf.h and libdwarf.h and this table. +*/ +static char *regnames[] = { + "cfa", + "r1/at", "r2/v0", "r3/v1", + "r4/a0", "r5/a1", "r6/a2", "r7/a3", + "r8/t0", "r9/t1", "r10/t2", "r11/t3", + "r12/t4", "r13/t5", "r14/t6", "r15/t7", + "r16/s0", "r17/s1", "r18/s2", "r19/s3", + "r20/s4", "r21/s5", "r22/s6", "r23/s7", + "r24/t8", "r25/t9", "r26/k0", "r27/k1", + "r28/gp", "r29/sp", "r30/s8", "r31", + + "$f0", "$f1", + "$f2", "$f3", + "$f4", "$f5", + "$f6", "$f7", + "$f8", "$f9", + "$f10", "$f11", + "$f12", "$f13", + "$f14", "$f15", + "$f16", "$f17", + "$f18", "$f19", + "$f20", "$f21", + "$f22", "$f23", + "$f24", "$f25", + "$f26", "$f27", + "$f28", "$f29", + "$f30", "$f31", + "ra", "slk", +}; + + +/* These defaults match MIPS/IRIX ABI defaults. + For a 'generic' ABI, see -R. + For other ABIs, see -x abi= + to configure dwarfdump (and libdwarf) frame + data reporting at runtime. +*/ +void +init_conf_file_data(struct dwconf_s *config_file_data) +{ + unsigned long base_table_count = + sizeof(regnames) / sizeof(regnames[0]); + + memset(config_file_data, 0, sizeof(*config_file_data)); + config_file_data->cf_interface_number = 2; + config_file_data->cf_table_entry_count = DW_REG_TABLE_SIZE; + config_file_data->cf_initial_rule_value = + DW_FRAME_REG_INITIAL_VALUE; + config_file_data->cf_cfa_reg = DW_FRAME_CFA_COL; + config_file_data->cf_regs = regnames; + config_file_data->cf_named_regs_table_size = base_table_count; + config_file_data->cf_regs_malloced = 0; + if (config_file_data->cf_table_entry_count != base_table_count) { + printf("dwarfdump: improper base table initization, " + "header files wrong: " + "DW_REG_TABLE_SIZE %u != string table size %lu\n", + (unsigned) DW_REG_TABLE_SIZE, + (unsigned long) base_table_count); + exit(1); + } + + return; +} + +/* Naming a few registers makes printing these just + a little bit faster. +*/ +static char *genericregnames[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", + "r20", +}; + +/* A 'generic' ABI. For up to 1000 registers. + Perhaps cf_initial_rule_value should be d + UNDEFINED VALUE (1034) instead, but for the purposes of + getting the dwarfdump output correct + either will work. +*/ +void +init_generic_config_1000_regs(struct dwconf_s *config_file_data) +{ + unsigned long generic_table_count = + sizeof(genericregnames) / sizeof(genericregnames[0]); + config_file_data->cf_interface_number = 3; + config_file_data->cf_table_entry_count = 1000; + config_file_data->cf_initial_rule_value = 1035; /* SAME VALUE */ + config_file_data->cf_cfa_reg = 1036; + config_file_data->cf_regs = genericregnames; + config_file_data->cf_named_regs_table_size = generic_table_count; + config_file_data->cf_regs_malloced = 0; +} + +/* Print the 'right' string for the register we are given. + Deal sensibly with the special regs as well as numbers + we know and those we have not been told about. + +*/ +void +print_reg_from_config_data(Dwarf_Signed reg, + struct dwconf_s *config_data) +{ + char *name = 0; + + if (reg == config_data->cf_cfa_reg) { + fputs("cfa",stdout); + return; + } + if (reg == DW_FRAME_CFA_COL3) { + /* This should not be necessary, but sometimes one forgets to + do the cfa_reg: command in dwarfdump.conf */ + fputs("cfa",stdout); + return; + } + if (reg == DW_FRAME_UNDEFINED_VAL) { + fputs("u",stdout); + return; + } + if (reg == DW_FRAME_SAME_VAL) { + fputs("s",stdout); + return; + } + if (config_data->cf_regs == 0 || + reg < 0 || reg > config_data->cf_named_regs_table_size) { + printf("r%lld", (signed long long) reg); + return; + } + name = config_data->cf_regs[reg]; + if (!name) { + /* Can happen, the reg names table can be sparse. */ + printf("r%lld", (signed long long) reg); + return; + } + fputs(name,stdout); + return; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwconf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwconf.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,91 @@ +/* + Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + +$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/dwconf.h,v 1.2 2006/04/18 04:29:39 davea Exp $ */ + + +/* + declarations helping configure the frame reader. +*/ +struct dwconf_s { + char *cf_config_file_path; + char *cf_abi_name; + + /* 2 for old, 3 for frame interface 3. 2 means use the old + mips-abi-oriented frame interface. 3 means use the new + DWARF3-capable and configureable-abi interface. + + Now, anyone who revises dwarf.h and libdwarf.h to match their + abi-of-interest will still be able to use cf_interface_number 2 + as before. But most folks don't update those header files and + instead of making *them* configurable we make dwarfdump (and + libdwarf) configurable sufficiently to print frame information + sensibly. */ + int cf_interface_number; + + /* The number of table rules , aka columns. For MIPS/IRIX is 66. */ + unsigned long cf_table_entry_count; + + /* Array of cf_table_entry_count reg names. Names not filled in + from dwarfdump.conf have NULL (0) pointer value. + cf_named_regs_table_size must match size of cf_regs array. + Set cf_regs_malloced 1 if table was malloced. Set 0 + if static. + */ + char **cf_regs; + unsigned long cf_named_regs_table_size; + int cf_regs_malloced; + + /* The 'default initial value' when intializing a table. for MIPS + is DW_FRAME_SAME_VAL(1035). For other ISA/ABIs may be + DW_FRAME_UNDEFINED_VAL(1034). */ + int cf_initial_rule_value; + + /* The number of the cfa 'register'. For cf_interface_number 2 of + MIPS this is 0. For other architectures (and anytime using + cf_interface_number 3) this should be outside the table, a + special value such as 1036, not a table column at all). */ + int cf_cfa_reg; +}; + + +/* Returns DW_DLV_OK if works. DW_DLV_ERROR if cannot do what is asked. */ +int find_conf_file_and_read_config(char *named_file, + char *named_abi, char **defaults, + struct dwconf_s *conf_out); +void init_conf_file_data(struct dwconf_s *config_file_data); + +void print_reg_from_config_data(Dwarf_Signed reg, + struct dwconf_s *config_data); + + +void init_generic_config_1000_regs(struct dwconf_s *conf); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/esb.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/esb.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,210 @@ +/* + Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + +$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/esb.c,v 1.1 2005/08/04 05:09:37 davea Exp $ */ + +/* esb.c + extensible string buffer. + + A simple means (vaguely like a C++ class) that + enables safely saving strings of arbitrary length built up + in small pieces. + +*/ + +#include "globals.h" +#include "esb.h" + +#define INITIAL_ALLOC 1024 +static size_t alloc_size = INITIAL_ALLOC; + + +static void +init_esb_string(struct esb_s *data, size_t min_len) +{ + string d; + + if (data->esb_allocated_size > 0) { + return; + } + if (min_len < alloc_size) { + min_len = alloc_size; + } + d = malloc(min_len); + if (!d) { + fprintf(stderr, + "dwarfdump is out of memory allocating %lu bytes\n", + (unsigned long) min_len); + exit(5); + } + data->esb_string = d; + data->esb_allocated_size = min_len; + data->esb_string[0] = 0; + data->esb_used_bytes = 0; +} + +/* Make more room. Leaving contents unchanged, effectively. +*/ +static void +allocate_more(struct esb_s *data, size_t len) +{ + size_t new_size = data->esb_allocated_size + len; + string newd = 0; + + if (new_size < alloc_size) + new_size = alloc_size; + newd = realloc(data->esb_string, new_size); + if (!newd) { + fprintf(stderr, "dwarfdump is out of memory re-allocating " + "%lu bytes\n", (unsigned long) new_size); + exit(5); + } + data->esb_string = newd; + data->esb_allocated_size = new_size; +} + +static void + esb_appendn_internal(struct esb_s *data, string in_string, size_t len); + +void +esb_appendn(struct esb_s *data, string in_string, size_t len) +{ + size_t full_len = strlen(in_string); + + if (full_len < len) { + fprintf(stderr, "dwarfdump internal error, bad string length " + " %lu < %lu \n", + (unsigned long) full_len, (unsigned long) len); + len = full_len; + } + + esb_appendn_internal(data, in_string, len); +} + +/* The length is gotten from the in_string itself. */ +void +esb_append(struct esb_s *data, string in_string) +{ + size_t len = strlen(in_string); + + esb_appendn_internal(data, in_string, len); +} + +/* The 'len' is believed. Do not pass in strings < len bytes long. */ +static void +esb_appendn_internal(struct esb_s *data, string in_string, size_t len) +{ + size_t remaining = 0; + size_t needed = len + 1; + + if (data->esb_allocated_size == 0) { + size_t maxlen = (len > alloc_size) ? len : alloc_size; + + init_esb_string(data, maxlen); + } + remaining = data->esb_allocated_size - data->esb_used_bytes; + if (remaining < needed) { + allocate_more(data, needed); + } + strncpy(&data->esb_string[data->esb_used_bytes], in_string, len); + data->esb_used_bytes += len; + /* Insist on explicit NUL terminator */ + data->esb_string[data->esb_used_bytes] = 0; +} + +/* Always returns an empty string or a non-empty string. Never 0. */ +string +esb_get_string(struct esb_s *data) +{ + if (data->esb_allocated_size == 0) { + init_esb_string(data, alloc_size); + } + return data->esb_string; +} + + +/* Sets esb_used_bytes to zero. The string is not freed and + esb_allocated_size is unchanged. */ +void +esb_empty_string(struct esb_s *data) +{ + if (data->esb_allocated_size == 0) { + init_esb_string(data, alloc_size); + } + data->esb_used_bytes = 0; + data->esb_string[0] = 0; + +} + + +/* Return esb_used_bytes. */ +size_t +esb_string_len(struct esb_s *data) +{ + return data->esb_used_bytes; +} + + +/* The following are for testing esb, not use by dwarfdump. */ + +/* *data is presumed to contain garbage, not values, and + is properly initialized. */ +void +esb_constructor(struct esb_s *data) +{ + memset(data, 0, sizeof(*data)); +} + +/* The string is freed, contents of *data set to zeroes. */ +void +esb_destructor(struct esb_s *data) +{ + if (data->esb_string) { + free(data->esb_string); + } + esb_constructor(data); +} + + +/* To get all paths in the code tested, this sets the + allocation/reallocation to the given value, which can be quite small + but must not be zero. */ +void +esb_alloc_size(size_t size) +{ + alloc_size = size; +} + +size_t +esb_get_allocated_size(struct esb_s *data) +{ + return data->esb_allocated_size; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/esb.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/esb.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,83 @@ +/* + Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + +$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/esb.h,v 1.1 2005/08/04 05:09:37 davea Exp $ */ + + +/* esb.h + Extensible string buffer. + A simple vaguely object oriented extensible string buffer. + + The struct could be opaque here, but it seems ok to expose + the contents: simplifies debugging. +*/ + + +struct esb_s { + string esb_string; /* pointer to the data itself, or NULL. */ + size_t esb_allocated_size; /* Size of allocated data or 0 */ + size_t esb_used_bytes; /* Amount of space used or 0 */ +}; + +/* string length taken from string itself. */ +void esb_append(struct esb_s *data, string in_string); + +/* The 'len' is believed. Do not pass in strings < len bytes long. */ +void esb_appendn(struct esb_s *data, string in_string, size_t len); + +/* Always returns an empty string or a non-empty string. Never 0. */ +string esb_get_string(struct esb_s *data); + + +/* Sets esb_used_bytes to zero. The string is not freed and + esb_allocated_size is unchanged. */ +void esb_empty_string(struct esb_s *data); + + +/* Return esb_used_bytes. */ +size_t esb_string_len(struct esb_s *data); + +/* The following are for testing esb, not use by dwarfdump. */ + +/* *data is presumed to contain garbage, not values, and + is properly initialized. */ +void esb_constructor(struct esb_s *data); + +/* The string is freed, contents of *data set to zeroes. */ +void esb_destructor(struct esb_s *data); + + +/* To get all paths in the code tested, this sets the + allocation/reallocation to the given value, which can be quite small + but must not be zero. */ +void esb_alloc_size(size_t size); +size_t esb_get_allocated_size(struct esb_s *data); + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/globals.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/globals.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,231 @@ +/* + Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + + +$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/globals.h,v 1.25 2006/04/17 00:09:56 davea Exp $ */ + +#ifndef globals_INCLUDED +#define globals_INCLUDED + +#include "config.h" +#if (!defined(HAVE_RAW_LIBELF_OK) && defined(HAVE_LIBELF_OFF64_OK) ) +/* At a certain point libelf.h requires _GNU_SOURCE. + here we assume the criteria in configure determine that + usefully. +*/ +#define _GNU_SOURCE 1 +#endif + + +/* We want __uint32_t and __uint64_t and __int32_t __int64_t + properly defined but not duplicated, since duplicate typedefs + are not legal C. +*/ +/* + HAVE___UINT32_T + HAVE___UINT64_T will be set by configure if + our 4 types are predefined in compiler +*/ + + +#if (!defined(HAVE___UINT32_T)) && defined(HAVE_SGIDEFS_H) +#include /* sgidefs.h defines them */ +#define HAVE___UINT32_T 1 +#define HAVE___UINT64_T 1 +#endif + + + +#if (!defined(HAVE___UINT32_T)) && defined(HAVE_SYS_TYPES_H) && defined(HAVE___UINT32_T_IN_SYS_TYPES_H) +# include +/* we assume __[u]int32_t and __[u]int64_t defined + since __uint32_t defined in the sys/types.h in use */ +#define HAVE___UINT32_T 1 +#define HAVE___UINT64_T 1 +#endif + +#ifndef HAVE___UINT32_T +typedef int __int32_t; +typedef unsigned __uint32_t; +#define HAVE___UINT32_T 1 +#endif +#ifndef HAVE___UINT64_T +typedef long long __int64_t; +typedef unsigned long long __uint64_t; +#define HAVE___UINT64_T 1 +#endif + + +#include +#include +#include +#ifdef HAVE_ELF_H +#include +#endif +#ifdef HAVE_LIBELF_H +#include +#else +#ifdef HAVE_LIBELF_LIBELF_H +#include +#endif +#endif +#include +#include + +typedef char * string; +typedef int boolean; +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +/* size of attrib_buffer, defined in print_die.c */ +#define ATTRIB_BUFSIZ 999 + +typedef struct { + int checks; + int errors; +} Dwarf_Check_Result; + +extern int verbose; +extern boolean dense; +extern boolean ellipsis; +extern boolean dst_format; +extern boolean use_mips_regnames; +extern boolean show_global_offsets; + +extern boolean check_pubname_attr; +extern boolean check_attr_tag; +extern boolean check_tag_tree; +extern boolean check_type_offset; + +extern Dwarf_Check_Result abbrev_code_result; +extern Dwarf_Check_Result pubname_attr_result; +extern Dwarf_Check_Result reloc_offset_result; +extern Dwarf_Check_Result attr_tag_result; +extern Dwarf_Check_Result tag_tree_result; +extern Dwarf_Check_Result type_offset_result; + +extern boolean info_flag; +extern boolean use_old_dwarf_loclist; + +extern char cu_name[ ]; +extern boolean cu_name_flag; +extern Dwarf_Unsigned cu_offset; +extern Dwarf_Off fde_offset_for_cu_low; +extern Dwarf_Off fde_offset_for_cu_high; + + +extern int check_error; +extern Dwarf_Error err; +extern void print_error (Dwarf_Debug dbg, string msg,int res, Dwarf_Error err); + +extern void print_line_numbers_this_cu (Dwarf_Debug dbg, Dwarf_Die in_die); +struct dwconf_s; +extern void print_frames (Dwarf_Debug dbg, int print_debug_frame, + int print_eh_frame,struct dwconf_s *); +extern void print_pubnames (Dwarf_Debug dbg); +extern void print_macinfo (Dwarf_Debug dbg); +extern void print_locs (Dwarf_Debug dbg); +extern void print_abbrevs (Dwarf_Debug dbg); +extern void print_strings (Dwarf_Debug dbg); +extern void print_aranges (Dwarf_Debug dbg); +extern void print_relocinfo (Dwarf_Debug dbg); +extern void print_static_funcs(Dwarf_Debug dbg); +extern void print_static_vars(Dwarf_Debug dbg); +enum type_type_e {SGI_TYPENAME, DWARF_PUBTYPES} ; +extern void print_types(Dwarf_Debug dbg,enum type_type_e type_type); +extern void print_weaknames(Dwarf_Debug dbg); +extern void print_exception_tables(Dwarf_Debug dbg); +extern string get_fde_proc_name(Dwarf_Debug dbg, Dwarf_Addr low_pc); +extern void print_die_and_children( + Dwarf_Debug dbg, + Dwarf_Die in_die, + char **srcfiles, + Dwarf_Signed cnt); +extern void print_one_die( + Dwarf_Debug dbg, + Dwarf_Die die, + boolean print_information, + char **srcfiles, + Dwarf_Signed cnt); + +#define DWARF_CHECK_ERROR(str) {\ + printf("*** DWARF CHECK: %s ***\n", str);\ + check_error ++; \ +} + +#define DWARF_CHECK_ERROR2(str1, str2) {\ + printf("*** DWARF CHECK: %s: %s ***\n", str1, str2);\ + check_error ++; \ +} + +#define DWARF_CHECK_ERROR3(str1, str2,strexpl) {\ + printf("*** DWARF CHECK: %s -> %s: %s ***\n", str1, str2,strexpl);\ + check_error ++; \ +} + +struct esb_s; +extern Dwarf_Die current_cu_die_for_print_frames; /* This is + an awful hack, making this public. But it enables + cleaning up (doing all dealloc needed). */ +extern void printreg(Dwarf_Signed reg,struct dwconf_s *config_data); +extern void print_frame_inst_bytes(Dwarf_Debug dbg, + Dwarf_Ptr cie_init_inst, Dwarf_Signed len, + Dwarf_Signed data_alignment_factor, + int code_alignment_factor, Dwarf_Half addr_size, + struct dwconf_s *config_data); + + +extern Dwarf_Unsigned local_dwarf_decode_u_leb128(unsigned char *leb128, + unsigned int *leb128_length); + +extern Dwarf_Signed local_dwarf_decode_s_leb128(unsigned char *leb128, + unsigned int *leb128_length); + +extern void dump_block(char *prefix, char *data, Dwarf_Signed len); + +int +dwarfdump_print_one_locdesc(Dwarf_Debug dbg, + Dwarf_Locdesc * llbuf, + int skip_locdesc_header, + struct esb_s *string_out); +void clean_up_die_esb(); +void clean_up_syms_malloc_data(); + + + + +#endif /* globals_INCLUDED */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/install.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/install.sh Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,119 @@ +#!/bin/sh + +# +# install - install a program, script, or datafile +# This comes from X11R5; it is not part of GNU. +# +# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" + +instcmd="$mvprog" +chmodcmd="" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +fi + +if [ x"$dst" = x ] +then + echo "install: no destination specified" + exit 1 +fi + + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + +if [ -d $dst ] +then + dst="$dst"/`basename $src` +fi + +# Make a temp file name in the proper directory. + +dstdir=`dirname $dst` +dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + +$doit $instcmd $src $dsttmp + +# and set any options; do chmod last to preserve setuid bits + +if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi +if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi +if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi +if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi + +# Now rename the file to the real destination. + +$doit $rmcmd $dst +$doit $mvcmd $dsttmp $dst + + +exit 0 diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/makename.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/makename.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,68 @@ + +/* + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + makename.c + $Revision: 1.4 $ + $Date: 2005/11/08 21:48:42 $ + + This used to be elaborate stuff. + Now it is trivial, as duplicating names is + unimportant in dwarfdump (in general). + + And in fact, this is only called for attributes and + tags etc whose true name is unknown. Not for + any normal case. + +*/ + +#include +#include +#include +#include "makename.h" + +char * +makename(char *s) +{ + char *newstr; + + if (!s) { + return ""; + } + + newstr = strdup(s); + if (newstr == 0) { + fprintf(stderr, "Out of memory mallocing %d bytes\n", + (int) strlen(s)); + exit(1); + } + return newstr; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/makename.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/makename.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,53 @@ +#ifndef names_h +#define names_h +/* + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + makename.h + $Revision: 1.3 $ + $Date: 2004/10/28 22:26:58 $ + + This is for putting strings into stable storage. + + Effectively an strdup() wrapper. + + Rarely called. + + It leaks memory, (the memory + is never freed) but that seems unimportant since + use of this is very rare. + +*/ + +char * makename(char *); /* makes a copy of the string in + a malloc area. Can never return 0. */ + +#endif diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_die.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_die.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1313 @@ +/* + Copyright (C) 2000,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved. + Portions Copyright 2007 David Anderson. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + +$ Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_die.c,v 1.51 2006/04/01 16:20:21 davea Exp $ */ + +#include "globals.h" +#include "dwarf_names.h" +#include "esb.h" /* For flexible string buffer. */ +#include "makename.h" /* Non-duplicating string table. */ + +static void get_attr_value(Dwarf_Debug dbg, Dwarf_Half tag, + Dwarf_Attribute attrib, + char **srcfiles, + Dwarf_Signed cnt, struct esb_s *esbp); +static void print_attribute(Dwarf_Debug dbg, Dwarf_Die die, + Dwarf_Half attr, + Dwarf_Attribute actual_addr, + boolean print_information, char **srcfiles, + Dwarf_Signed cnt); +static void get_location_list(Dwarf_Debug dbg, Dwarf_Die die, + Dwarf_Attribute attr, struct esb_s *esbp); +static int tag_attr_combination(Dwarf_Half tag, Dwarf_Half attr); +static int _dwarf_print_one_expr_op(Dwarf_Debug dbg,Dwarf_Loc* expr,int index, struct esb_s *string_out); + +/* esb_base is static so gets initialized to zeros. + It is not thread-safe or + safe for multiple open producer instances for + but that does not matter here in dwarfdump. + + The memory used by esb_base is never freed. +*/ +static struct esb_s esb_base; + +static int indent_level = 0; +static boolean local_symbols_already_began = FALSE; + +typedef string(*encoding_type_func) (Dwarf_Debug dbg, Dwarf_Half val); + +Dwarf_Off fde_offset_for_cu_low = DW_DLV_BADOFFSET; +Dwarf_Off fde_offset_for_cu_high = DW_DLV_BADOFFSET; + +/* Dwarf_Half list_of_attrs[] */ +/*#include "at_list.i" unreferenced */ + +#define DIE_STACK_SIZE 300 +static Dwarf_Die die_stack[DIE_STACK_SIZE]; + +#define PUSH_DIE_STACK(x) { die_stack[indent_level] = x; } +#define POP_DIE_STACK { die_stack[indent_level] = 0; } + +#include "_tag_tree_table.c" + +/* + Look only at valid table entries + The check here must match the building-logic in + tag_tree.c + And must match the tags defined in dwarf.h +*/ +#define MAX_CHECKED_TAG_ID 0x35 +static int +tag_tree_combination(Dwarf_Half tag_parent, Dwarf_Half tag_child) +{ + if (tag_parent > 0 && tag_parent <= MAX_CHECKED_TAG_ID + && tag_child > 0 && tag_child <= MAX_CHECKED_TAG_ID) { + return ((tag_tree_combination_table[tag_parent] + [tag_child / 0x20] + & (1 << (tag_child % 0x20))) > 0 ? TRUE : FALSE); + } else + return (FALSE); +} + +/* recursively follow the die tree */ +extern void +print_die_and_children(Dwarf_Debug dbg, Dwarf_Die in_die_in, + char **srcfiles, Dwarf_Signed cnt) +{ + Dwarf_Die child; + Dwarf_Die sibling; + Dwarf_Error err; + int tres; + int cdres; + Dwarf_Die in_die = in_die_in; + + for (;;) { + PUSH_DIE_STACK(in_die); + + if (check_tag_tree) { + tag_tree_result.checks++; + if (indent_level == 0) { + Dwarf_Half tag; + + tres = dwarf_tag(in_die, &tag, &err); + if (tres != DW_DLV_OK) { + tag_tree_result.errors++; + DWARF_CHECK_ERROR + ("Tag-tree root is not DW_TAG_compile_unit") + } else if (tag == DW_TAG_compile_unit) { + /* OK */ + } else { + tag_tree_result.errors++; + DWARF_CHECK_ERROR + ("tag-tree root is not DW_TAG_compile_unit") + } + } else { + Dwarf_Half tag_parent, tag_child; + int pres; + int cres; + char *ctagname = ""; + char *ptagname = ""; + + pres = + dwarf_tag(die_stack[indent_level - 1], &tag_parent, + &err); + cres = dwarf_tag(in_die, &tag_child, &err); + if (pres != DW_DLV_OK) + tag_parent = 0; + if (cres != DW_DLV_OK) + tag_child = 0; + if (cres != DW_DLV_OK || pres != DW_DLV_OK) { + if (cres == DW_DLV_OK) { + ctagname = get_TAG_name(dbg, tag_child); + } + if (pres == DW_DLV_OK) { + ptagname = get_TAG_name(dbg, tag_parent); + } + DWARF_CHECK_ERROR3(ptagname, + ctagname, + "Tag-tree relation is not standard.."); + } else if (tag_tree_combination(tag_parent, tag_child)) { + /* OK */ + } else { + DWARF_CHECK_ERROR3(get_TAG_name(dbg, tag_parent), + get_TAG_name(dbg, tag_child), + "tag-tree relation is not standard."); + } + } + } + + /* here to pre-descent processing of the die */ + print_one_die(dbg, in_die, info_flag, srcfiles, cnt); + + cdres = dwarf_child(in_die, &child, &err); + /* child first: we are doing depth-first walk */ + if (cdres == DW_DLV_OK) { + indent_level++; + if(indent_level >= DIE_STACK_SIZE ) { + print_error(dbg, + "compiled in DIE_STACK_SIZE limit exceeded", + DW_DLV_OK,err); + } + print_die_and_children(dbg, child, srcfiles, cnt); + indent_level--; + if (indent_level == 0) + local_symbols_already_began = FALSE; + dwarf_dealloc(dbg, child, DW_DLA_DIE); + } else if (cdres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_child", cdres, err); + } + + cdres = dwarf_siblingof(dbg, in_die, &sibling, &err); + if (cdres == DW_DLV_OK) { + /* print_die_and_children(dbg, sibling, srcfiles, cnt); We + loop around to actually print this, rather than + recursing. Recursing is horribly wasteful of stack + space. */ + } else if (cdres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_siblingof", cdres, err); + } + + /* Here do any post-descent (ie post-dwarf_child) processing of + the in_die. */ + + POP_DIE_STACK; + if (in_die != in_die_in) { + /* Dealloc our in_die, but not the argument die, it belongs + to our caller. Whether the siblingof call worked or not. + */ + dwarf_dealloc(dbg, in_die, DW_DLA_DIE); + } + if (cdres == DW_DLV_OK) { + /* Set to process the sibling, loop again. */ + in_die = sibling; + } else { + /* We are done, no more siblings at this level. */ + + break; + } + } /* end for loop on siblings */ + return; +} + +#define SPACE(x) { register int i; for (i=0;i:\n", + overall_offset - offset); + } + } else if (local_symbols_already_began == FALSE && + indent_level == 1 && !dense) { + printf("\nLOCAL_SYMBOLS:\n"); + local_symbols_already_began = TRUE; + } + if (dense) { + if (show_global_offsets) { + if (indent_level == 0) { + printf("<%d><%llu+%llu GOFF=%llu><%s>", indent_level, + overall_offset - offset, offset, + overall_offset, tagname); + } else { + printf("<%d><%llu GOFF=%llu><%s>", indent_level, + offset, overall_offset, tagname); + } + } else { + if (indent_level == 0) { + printf("<%d><%llu+%llu><%s>", indent_level, + overall_offset - offset, offset, tagname); + } else { + printf("<%d><%llu><%s>", indent_level, offset, tagname); + } + } + } else { + if (show_global_offsets) { + printf("<%d><%5llu GOFF=%llu>\t%s\n", indent_level, offset, + overall_offset, tagname); + } else { + printf("<%d><%5llu>\t%s\n", indent_level, offset, tagname); + } + } + } + + atres = dwarf_attrlist(die, &atlist, &atcnt, &err); + if (atres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_attrlist", atres, err); + } else if (atres == DW_DLV_NO_ENTRY) { + /* indicates there are no attrs. It is not an error. */ + atcnt = 0; + } + + + for (i = 0; i < atcnt; i++) { + Dwarf_Half attr; + int ares; + + ares = dwarf_whatattr(atlist[i], &attr, &err); + if (ares == DW_DLV_OK) { + print_attribute(dbg, die, attr, + atlist[i], + print_information, srcfiles, cnt); + } else { + print_error(dbg, "dwarf_whatattr entry missing", ares, err); + } + } + + for (i = 0; i < atcnt; i++) { + dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR); + } + if (atres == DW_DLV_OK) { + dwarf_dealloc(dbg, atlist, DW_DLA_LIST); + } + + if (dense && print_information) { + printf("\n\n"); + } + return; +} + +/* Encodings have undefined signedness. Accept either + signedness. The values are small (they are defined + in the DWARF specification), so the + form the compiler uses (as long as it is + a constant value) is a non-issue. + + If string_out is non-NULL, construct a string output, either + an error message or the name of the encoding. + The function pointer passed in is to code generated + by a script at dwarfdump build time. The code for + the val_as_string function is generated + from dwarf.h. See /dwarf_names.c + + If string_out is non-NULL then attr_name and val_as_string + must also be non-NULL. + +*/ +int +get_small_encoding_integer_and_name(Dwarf_Debug dbg, + Dwarf_Attribute attrib, + Dwarf_Unsigned * uval_out, + char *attr_name, + string * string_out, + encoding_type_func val_as_string, + Dwarf_Error * err) +{ + Dwarf_Unsigned uval = 0; + char buf[100]; /* The strings are small. */ + int vres = dwarf_formudata(attrib, &uval, err); + + if (vres != DW_DLV_OK) { + Dwarf_Signed sval = 0; + + vres = dwarf_formsdata(attrib, &sval, err); + if (vres != DW_DLV_OK) { + if (string_out != 0) { + snprintf(buf, sizeof(buf), + "%s has a bad form.", attr_name); + *string_out = makename(buf); + } + return vres; + } + *uval_out = (Dwarf_Unsigned) sval; + } else { + *uval_out = uval; + } + if (string_out) + *string_out = val_as_string(dbg, (Dwarf_Half) uval); + + return DW_DLV_OK; + +} + + + + +/* + * We need a 32-bit signed number here, but there's no portable + * way of getting that. So use __uint32_t instead. It's supplied + * in a reliable way by the autoconf infrastructure. + */ + +static void +get_FLAG_BLOCK_string(Dwarf_Debug dbg, Dwarf_Attribute attrib) +{ + int fres = 0; + Dwarf_Block *tempb = 0; + __uint32_t * array = 0; + Dwarf_Unsigned array_len = 0; + __uint32_t * array_ptr; + Dwarf_Unsigned array_remain = 0; + char linebuf[100]; + + esb_empty_string(&esb_base); + esb_append(&esb_base, "\n"); + + /* first get compressed block data */ + fres = dwarf_formblock (attrib,&tempb, &err); + if (fres != DW_DLV_OK) { + print_error(dbg,"DW_FORM_blockn cannot get block\n",fres,err); + return; + } + + /* uncompress block into int array */ + array = dwarf_uncompress_integer_block(dbg, + 1, /* 'true' (meaning signed ints)*/ + 32, /* bits per unit */ + tempb->bl_data, + tempb->bl_len, + &array_len, /* len of out array */ + &err); + if (array == (void*) DW_DLV_BADOFFSET) { + print_error(dbg,"DW_AT_SUN_func_offsets cannot uncompress data\n",0,err); + return; + } + if (array_len == 0) { + print_error(dbg,"DW_AT_SUN_func_offsets has no data\n",0,err); + return; + } + + /* fill in string buffer */ + array_remain = array_len; + array_ptr = array; + while (array_remain > 8) { + /* print a full line */ + /* if you touch this string, update the magic number 78 below! */ + snprintf(linebuf, sizeof(linebuf), + "\n %8x %8x %8x %8x %8x %8x %8x %8x", + array_ptr[0], array_ptr[1], + array_ptr[2], array_ptr[3], + array_ptr[4], array_ptr[5], + array_ptr[6], array_ptr[7]); + array_ptr += 8; + array_remain -= 8; + esb_append(&esb_base, linebuf); + } + + /* now do the last line */ + if (array_remain > 0) { + esb_append(&esb_base, "\n "); + while (array_remain > 0) { + snprintf(linebuf, sizeof(linebuf), " %8x", *array_ptr); + array_remain--; + array_ptr++; + esb_append(&esb_base, linebuf); + } + } + + /* free array buffer */ + dwarf_dealloc_uncompressed_block(dbg, array); + +} + +static void +print_attribute(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attr, + Dwarf_Attribute attr_in, + boolean print_information, + char **srcfiles, Dwarf_Signed cnt) +{ + Dwarf_Attribute attrib = 0; + Dwarf_Unsigned uval = 0; + string atname = 0; + string valname = 0; + int tres = 0; + Dwarf_Half tag = 0; + + atname = get_AT_name(dbg, attr); + + /* the following gets the real attribute, even in the face of an + incorrect doubling, or worse, of attributes */ + attrib = attr_in; + /* do not get attr via dwarf_attr: if there are (erroneously) + multiple of an attr in a DIE, dwarf_attr will not get the + second, erroneous one and dwarfdump will print the first one + multiple times. Oops. */ + + tres = dwarf_tag(die, &tag, &err); + if (tres == DW_DLV_ERROR) { + tag = 0; + } else if (tres == DW_DLV_NO_ENTRY) { + tag = 0; + } else { + /* ok */ + } + if (check_attr_tag) { + char *tagname = ""; + + attr_tag_result.checks++; + if (tres == DW_DLV_ERROR) { + attr_tag_result.errors++; + DWARF_CHECK_ERROR3(tagname, + get_AT_name(dbg, attr), + "check the tag-attr combination."); + } else if (tres == DW_DLV_NO_ENTRY) { + attr_tag_result.errors++; + DWARF_CHECK_ERROR3(tagname, + get_AT_name(dbg, attr), + "check the tag-attr combination..") + } else if (tag_attr_combination(tag, attr)) { + /* OK */ + } else { + attr_tag_result.errors++; + tagname = get_TAG_name(dbg, tag); + DWARF_CHECK_ERROR3(tagname, + get_AT_name(dbg, attr), + "check the tag-attr combination") + } + } + + switch (attr) { + case DW_AT_language: + get_small_encoding_integer_and_name(dbg, attrib, &uval, + "DW_AT_language", &valname, + get_LANG_name, &err); + break; + case DW_AT_accessibility: + get_small_encoding_integer_and_name(dbg, attrib, &uval, + "DW_AT_accessibility", + &valname, get_ACCESS_name, + &err); + break; + case DW_AT_visibility: + get_small_encoding_integer_and_name(dbg, attrib, &uval, + "DW_AT_visibility", + &valname, get_VIS_name, + &err); + break; + case DW_AT_virtuality: + get_small_encoding_integer_and_name(dbg, attrib, &uval, + "DW_AT_virtuality", + &valname, + get_VIRTUALITY_name, &err); + break; + case DW_AT_identifier_case: + get_small_encoding_integer_and_name(dbg, attrib, &uval, + "DW_AT_identifier", + &valname, get_ID_name, + &err); + break; + case DW_AT_inline: + get_small_encoding_integer_and_name(dbg, attrib, &uval, + "DW_AT_inline", &valname, + get_INL_name, &err); + break; + case DW_AT_encoding: + get_small_encoding_integer_and_name(dbg, attrib, &uval, + "DW_AT_encoding", &valname, + get_ATE_name, &err); + break; + case DW_AT_ordering: + get_small_encoding_integer_and_name(dbg, attrib, &uval, + "DW_AT_ordering", &valname, + get_ORD_name, &err); + break; + case DW_AT_calling_convention: + get_small_encoding_integer_and_name(dbg, attrib, &uval, + "DW_AT_calling_convention", + &valname, get_CC_name, + &err); + break; + case DW_AT_discr_list: /* DWARF3 */ + get_small_encoding_integer_and_name(dbg, attrib, &uval, + "DW_AT_discr_list", + &valname, get_DSC_name, + &err); + break; + case DW_AT_location: + case DW_AT_data_member_location: + case DW_AT_vtable_elem_location: + case DW_AT_string_length: + case DW_AT_return_addr: + case DW_AT_use_location: + case DW_AT_static_link: + case DW_AT_frame_base: + /* value is a location description or location list */ + esb_empty_string(&esb_base); + get_location_list(dbg, die, attrib, &esb_base); + valname = esb_get_string(&esb_base); + break; + case DW_AT_SUN_func_offsets: + get_FLAG_BLOCK_string(dbg, attrib); + valname = esb_get_string(&esb_base); + break; + case DW_AT_SUN_cf_kind: + { + Dwarf_Half kind; + Dwarf_Unsigned tempud; + Dwarf_Error err; + int wres; + wres = dwarf_formudata (attrib,&tempud, &err); + if(wres == DW_DLV_OK) { + kind = tempud; + valname = get_ATCF_name(dbg, kind); + } else if (wres == DW_DLV_NO_ENTRY) { + valname = "?"; + } else { + print_error(dbg,"Cannot get formudata....",wres,err); + valname = "??"; + } + } + break; + case DW_AT_upper_bound: + { + Dwarf_Half theform; + int rv; + rv = dwarf_whatform(attrib,&theform,&err); + /* depending on the form and the attribute, process the form */ + if(rv == DW_DLV_ERROR) { + print_error(dbg, "dwarf_whatform cannot find attr form", + rv, err); + } else if (rv == DW_DLV_NO_ENTRY) { + break; + } + + switch (theform) { + case DW_FORM_block1: + get_location_list(dbg, die, attrib, &esb_base); + valname = esb_get_string(&esb_base); + break; + default: + esb_empty_string(&esb_base); + get_attr_value(dbg, tag, attrib, srcfiles, cnt, &esb_base); + valname = esb_get_string(&esb_base); + break; + } + break; + } + case DW_AT_high_pc: + { + Dwarf_Half theform; + int rv; + rv = dwarf_whatform(attrib,&theform,&err); + /* depending on the form and the attribute, process the form */ + if(rv == DW_DLV_ERROR) { + print_error(dbg, "dwarf_whatform cannot find attr form", + rv, err); + } else if (rv == DW_DLV_NO_ENTRY) { + break; + } + esb_empty_string(&esb_base); + get_attr_value(dbg, tag, attrib, srcfiles, cnt, &esb_base); + if( theform != DW_FORM_addr) { + /* New in DWARF4: other forms are not an address + but are instead offset from pc. + One could test for DWARF4 here before adding + this string, but that seems unnecessary as this + could not happen with DWARF3 or earlier. + A normal consumer would have to add this value to + DW_AT_low_pc to get a grue pc. */ + esb_append(&esb_base,""); + } + valname = esb_get_string(&esb_base); + } + default: + esb_empty_string(&esb_base); + get_attr_value(dbg, tag, attrib, srcfiles, cnt, &esb_base); + valname = esb_get_string(&esb_base); + break; + } + if (print_information) { + if (dense) + printf(" %s<%s>", atname, valname); + else + printf("\t\t%-28s%s\n", atname, valname); + } +} + + +int +dwarfdump_print_one_locdesc(Dwarf_Debug dbg, + Dwarf_Locdesc * llbuf, + int skip_locdesc_header, + struct esb_s *string_out) +{ + + Dwarf_Locdesc *locd = 0; + Dwarf_Half no_of_ops = 0; + int i = 0; + char small_buf[100]; + + + if (!skip_locdesc_header && (verbose || llbuf->ld_from_loclist)) { + snprintf(small_buf, sizeof(small_buf), "", + (unsigned long long) llbuf->ld_lopc); + esb_append(string_out, small_buf); + + + snprintf(small_buf, sizeof(small_buf), "", + (unsigned long long) llbuf->ld_hipc); + esb_append(string_out, small_buf); + if (verbose) { + snprintf(small_buf, sizeof(small_buf), + "", + llbuf-> + ld_from_loclist ? ".debug_loc" : ".debug_info", + (unsigned long long) llbuf->ld_section_offset); + esb_append(string_out, small_buf); + + } + } + + + locd = llbuf; + no_of_ops = llbuf->ld_cents; + for (i = 0; i < no_of_ops; i++) { + Dwarf_Loc * op = &locd->ld_s[i]; + + int res = _dwarf_print_one_expr_op(dbg,op,i,string_out); + if(res == DW_DLV_ERROR) { + return res; + } + } + return DW_DLV_OK; +} + +int +_dwarf_print_one_expr_op(Dwarf_Debug dbg,Dwarf_Loc* expr,int index, + struct esb_s *string_out) +{ + /* local_space_needed is intended to be 'more than big enough' + for a short group of loclist entries. */ + char small_buf[100]; + Dwarf_Small op; + Dwarf_Unsigned opd1; + Dwarf_Unsigned opd2; + string op_name; + + + if (index > 0) + esb_append(string_out, " "); + + op = expr->lr_atom; + if (op > DW_OP_nop) { + print_error(dbg, "dwarf_op unexpected value", DW_DLV_OK, + err); + return DW_DLV_ERROR; + } + op_name = get_OP_name(dbg, op); + esb_append(string_out, op_name); + + opd1 = expr->lr_number; + if (op >= DW_OP_breg0 && op <= DW_OP_breg31) { + snprintf(small_buf, sizeof(small_buf), + "%+lld", (Dwarf_Signed) opd1); + esb_append(string_out, small_buf); + } else { + switch (op) { + case DW_OP_addr: + snprintf(small_buf, sizeof(small_buf), " %#llx", opd1); + esb_append(string_out, small_buf); + break; + case DW_OP_const1s: + case DW_OP_const2s: + case DW_OP_const4s: + case DW_OP_const8s: + case DW_OP_consts: + case DW_OP_skip: + case DW_OP_bra: + case DW_OP_fbreg: + snprintf(small_buf, sizeof(small_buf), + " %lld", (Dwarf_Signed) opd1); + esb_append(string_out, small_buf); + break; + case DW_OP_const1u: + case DW_OP_const2u: + case DW_OP_const4u: + case DW_OP_const8u: + case DW_OP_constu: + case DW_OP_pick: + case DW_OP_plus_uconst: + case DW_OP_regx: + case DW_OP_piece: + case DW_OP_deref_size: + case DW_OP_xderef_size: + snprintf(small_buf, sizeof(small_buf), " %llu", opd1); + esb_append(string_out, small_buf); + break; + case DW_OP_bregx: + snprintf(small_buf, sizeof(small_buf), "%llu", opd1); + esb_append(string_out, small_buf); + + + + opd2 = expr->lr_number2; + snprintf(small_buf, sizeof(small_buf), + "%+lld", (Dwarf_Signed) opd2); + esb_append(string_out, small_buf); + break; + default: + break; + } + } + return DW_DLV_OK; +} + +/* Fill buffer with location lists + Buffer esbp expands as needed. +*/ + /*ARGSUSED*/ static void +get_location_list(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Attribute attr, + struct esb_s *esbp) +{ + Dwarf_Locdesc *llbuf = 0; + Dwarf_Locdesc **llbufarray = 0; + Dwarf_Signed no_of_elements; + Dwarf_Error err; + int i; + int lres = 0; + int llent = 0; + int skip_locdesc_header = 0; + + + if (use_old_dwarf_loclist) { + + lres = dwarf_loclist(attr, &llbuf, &no_of_elements, &err); + if (lres == DW_DLV_ERROR) + print_error(dbg, "dwarf_loclist", lres, err); + if (lres == DW_DLV_NO_ENTRY) + return; + + dwarfdump_print_one_locdesc(dbg, llbuf,skip_locdesc_header,esbp); + dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK); + dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC); + return; + } + + lres = dwarf_loclist_n(attr, &llbufarray, &no_of_elements, &err); + if (lres == DW_DLV_ERROR) + print_error(dbg, "dwarf_loclist", lres, err); + if (lres == DW_DLV_NO_ENTRY) + return; + + for (llent = 0; llent < no_of_elements; ++llent) { + char small_buf[100]; + + llbuf = llbufarray[llent]; + + if (!dense && llbuf->ld_from_loclist) { + if (llent == 0) { + snprintf(small_buf, sizeof(small_buf), + "", + (long) no_of_elements); + esb_append(esbp, small_buf); + } + esb_append(esbp, "\n\t\t\t"); + snprintf(small_buf, sizeof(small_buf), "[%2d]", llent); + esb_append(esbp, small_buf); + } + lres = dwarfdump_print_one_locdesc(dbg, + llbuf, + skip_locdesc_header, + esbp); + if (lres == DW_DLV_ERROR) { + return; + } else { + /* DW_DLV_OK so we add follow-on at end, else is + DW_DLV_NO_ENTRY (which is impossible, treat like + DW_DLV_OK). */ + } + } + for (i = 0; i < no_of_elements; ++i) { + dwarf_dealloc(dbg, llbufarray[i]->ld_s, DW_DLA_LOC_BLOCK); + dwarf_dealloc(dbg, llbufarray[i], DW_DLA_LOCDESC); + } + dwarf_dealloc(dbg, llbufarray, DW_DLA_LIST); +} + +static void +formx_unsigned(Dwarf_Unsigned u, struct esb_s *esbp) +{ + char small_buf[40]; + snprintf(small_buf, sizeof(small_buf), + "%llu", (unsigned long long)u); + esb_append(esbp, small_buf); + +} +static void +formx_signed(Dwarf_Signed u, struct esb_s *esbp) +{ + char small_buf[40]; + snprintf(small_buf, sizeof(small_buf), + "%lld", (long long)u); + esb_append(esbp, small_buf); +} +/* We think this is an integer. Figure out how to print it. + In case the signedness is ambiguous (such as on + DW_FORM_data1 (ie, unknown signedness) print two ways. +*/ +static int +formxdata_print_value(Dwarf_Attribute attrib, struct esb_s *esbp, + Dwarf_Error * err) +{ + Dwarf_Signed tempsd = 0; + Dwarf_Unsigned tempud = 0; + int sres = 0; + int ures = 0; + Dwarf_Error serr = 0; + ures = dwarf_formudata(attrib, &tempud, err); + sres = dwarf_formsdata(attrib, &tempsd, &serr); + if(ures == DW_DLV_OK) { + if(sres == DW_DLV_OK) { + if(tempud == tempsd) { + /* Data is the same value, so makes no difference which + we print. */ + formx_unsigned(tempud,esbp); + } else { + formx_unsigned(tempud,esbp); + esb_append(esbp,"(as signed = "); + formx_signed(tempsd,esbp); + esb_append(esbp,")"); + } + } else if (sres == DW_DLV_NO_ENTRY) { + formx_unsigned(tempud,esbp); + } else /* DW_DLV_ERROR */{ + formx_unsigned(tempud,esbp); + } + return DW_DLV_OK; + } else if (ures == DW_DLV_NO_ENTRY) { + if(sres == DW_DLV_OK) { + formx_signed(tempsd,esbp); + return sres; + } else if (sres == DW_DLV_NO_ENTRY) { + return sres; + } else /* DW_DLV_ERROR */{ + *err = serr; + return sres; + } + } + /* else ures == DW_DLV_ERROR */ + if(sres == DW_DLV_OK) { + formx_signed(tempsd,esbp); + } else if (sres == DW_DLV_NO_ENTRY) { + return ures; + } + /* DW_DLV_ERROR */ + return ures; +} + + +/* Fill buffer with attribute value. + We pass in tag so we can try to do the right thing with + broken compiler DW_TAG_enumerator + + We append to esbp's buffer. + +*/ +static void +get_attr_value(Dwarf_Debug dbg, Dwarf_Half tag, Dwarf_Attribute attrib, + char **srcfiles, Dwarf_Signed cnt, struct esb_s *esbp) +{ + Dwarf_Half theform; + string temps; + Dwarf_Block *tempb; + Dwarf_Signed tempsd = 0; + Dwarf_Unsigned tempud = 0; + int i; + Dwarf_Half attr; + Dwarf_Off off; + Dwarf_Die die_for_check; + Dwarf_Half tag_for_check; + Dwarf_Bool tempbool; + Dwarf_Addr addr = 0; + int fres; + int bres; + int wres; + int dres; + Dwarf_Half direct_form = 0; + char small_buf[100]; + + + fres = dwarf_whatform(attrib, &theform, &err); + /* depending on the form and the attribute, process the form */ + if (fres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_whatform cannot find attr form", fres, + err); + } else if (fres == DW_DLV_NO_ENTRY) { + return; + } + + dwarf_whatform_direct(attrib, &direct_form, &err); + /* ignore errors in dwarf_whatform_direct() */ + + + switch (theform) { + case DW_FORM_addr: + bres = dwarf_formaddr(attrib, &addr, &err); + if (bres == DW_DLV_OK) { + snprintf(small_buf, sizeof(small_buf), "%#llx", + (unsigned long long) addr); + esb_append(esbp, small_buf); + } else { + print_error(dbg, "addr formwith no addr?!", bres, err); + } + break; + case DW_FORM_ref_addr: + /* DW_FORM_ref_addr is not accessed thru formref: ** it is an + address (global section offset) in ** the .debug_info + section. */ + bres = dwarf_global_formref(attrib, &off, &err); + if (bres == DW_DLV_OK) { + snprintf(small_buf, sizeof(small_buf), + "", + (unsigned long long) off); + esb_append(esbp, small_buf); + } else { + print_error(dbg, + "DW_FORM_ref_addr form with no reference?!", + bres, err); + } + break; + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: + bres = dwarf_formref(attrib, &off, &err); + if (bres != DW_DLV_OK) { + print_error(dbg, "ref formwith no ref?!", bres, err); + } + /* do references inside <> to distinguish them ** from + constants. In dense form this results in <<>>. Ugly for + dense form, but better than ambiguous. davea 9/94 */ + snprintf(small_buf, sizeof(small_buf), "<%llu>", off); + esb_append(esbp, small_buf); + if (check_type_offset) { + wres = dwarf_whatattr(attrib, &attr, &err); + if (wres == DW_DLV_ERROR) { + + } else if (wres == DW_DLV_NO_ENTRY) { + } + if (attr == DW_AT_type) { + dres = dwarf_offdie(dbg, cu_offset + off, + &die_for_check, &err); + type_offset_result.checks++; + if (dres != DW_DLV_OK) { + type_offset_result.errors++; + DWARF_CHECK_ERROR + ("DW_AT_type offset does not point to type info") + } else { + int tres2; + + tres2 = + dwarf_tag(die_for_check, &tag_for_check, &err); + if (tres2 == DW_DLV_OK) { + switch (tag_for_check) { + case DW_TAG_array_type: + case DW_TAG_class_type: + case DW_TAG_enumeration_type: + case DW_TAG_pointer_type: + case DW_TAG_reference_type: + case DW_TAG_string_type: + case DW_TAG_structure_type: + case DW_TAG_subroutine_type: + case DW_TAG_typedef: + case DW_TAG_union_type: + case DW_TAG_ptr_to_member_type: + case DW_TAG_set_type: + case DW_TAG_subrange_type: + case DW_TAG_base_type: + case DW_TAG_const_type: + case DW_TAG_file_type: + case DW_TAG_packed_type: + case DW_TAG_thrown_type: + case DW_TAG_volatile_type: + /* OK */ + break; + default: + type_offset_result.errors++; + DWARF_CHECK_ERROR + ("DW_AT_type offset does not point to type info") + break; + } + dwarf_dealloc(dbg, die_for_check, DW_DLA_DIE); + } else { + type_offset_result.errors++; + DWARF_CHECK_ERROR + ("DW_AT_type offset does not exist") + } + } + } + } + break; + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + fres = dwarf_formblock(attrib, &tempb, &err); + if (fres == DW_DLV_OK) { + for (i = 0; i < tempb->bl_len; i++) { + snprintf(small_buf, sizeof(small_buf), "%02x", + *(i + (unsigned char *) tempb->bl_data)); + esb_append(esbp, small_buf); + } + dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); + } else { + print_error(dbg, "DW_FORM_blockn cannot get block\n", fres, + err); + } + break; + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + fres = dwarf_whatattr(attrib, &attr, &err); + if (fres == DW_DLV_ERROR) { + print_error(dbg, "FORM_datan cannot get attr", fres, err); + } else if (fres == DW_DLV_NO_ENTRY) { + print_error(dbg, "FORM_datan cannot get attr", fres, err); + } else { + switch (attr) { + case DW_AT_ordering: + case DW_AT_byte_size: + case DW_AT_bit_offset: + case DW_AT_bit_size: + case DW_AT_inline: + case DW_AT_language: + case DW_AT_visibility: + case DW_AT_virtuality: + case DW_AT_accessibility: + case DW_AT_address_class: + case DW_AT_calling_convention: + case DW_AT_discr_list: /* DWARF3 */ + case DW_AT_encoding: + case DW_AT_identifier_case: + case DW_AT_MIPS_loop_unroll_factor: + case DW_AT_MIPS_software_pipeline_depth: + case DW_AT_decl_column: + case DW_AT_decl_file: + case DW_AT_decl_line: + case DW_AT_start_scope: + case DW_AT_byte_stride: + case DW_AT_bit_stride: + case DW_AT_count: + case DW_AT_stmt_list: + case DW_AT_MIPS_fde: + wres = get_small_encoding_integer_and_name(dbg, + attrib, + &tempud, + /* attrname */ + (char *) NULL, + /* err_string + */ + (char **) + NULL, + (encoding_type_func) 0, + &err); + + if (wres == DW_DLV_OK) { + snprintf(small_buf, sizeof(small_buf), "%llu", + tempud); + esb_append(esbp, small_buf); + if (attr == DW_AT_decl_file) { + if (srcfiles && tempud > 0 && tempud <= cnt) { + /* added by user request */ + /* srcfiles is indexed starting at 0, but + DW_AT_decl_file defines that 0 means no + file, so tempud 1 means the 0th entry in + srcfiles, thus tempud-1 is the correct + index into srcfiles. */ + char *fname = srcfiles[tempud - 1]; + + esb_append(esbp, " "); + esb_append(esbp, fname); + } + } + } else { + print_error(dbg, "Cannot get encoding attribute ..", + wres, err); + } + break; + case DW_AT_const_value: + wres = formxdata_print_value(attrib,esbp, &err); + if(wres == DW_DLV_OK){ + /* String appended already. */ + } else if (wres == DW_DLV_NO_ENTRY) { + /* nothing? */ + } else { + print_error(dbg,"Cannot get DW_AT_const_value ",wres,err); + } + + + break; + case DW_AT_upper_bound: + case DW_AT_lower_bound: + default: + wres = formxdata_print_value(attrib,esbp, &err); + if (wres == DW_DLV_OK) { + /* String appended already. */ + } else if (wres == DW_DLV_NO_ENTRY) { + /* nothing? */ + } else { + print_error(dbg, "Cannot get formsdata..", wres, + err); + } + break; + } + } + if (cu_name_flag) { + if (attr == DW_AT_MIPS_fde) { + if (fde_offset_for_cu_low == DW_DLV_BADOFFSET) { + fde_offset_for_cu_low + = fde_offset_for_cu_high = tempud; + } else if (tempud < fde_offset_for_cu_low) { + fde_offset_for_cu_low = tempud; + } else if (tempud > fde_offset_for_cu_high) { + fde_offset_for_cu_high = tempud; + } + } + } + break; + case DW_FORM_sdata: + wres = dwarf_formsdata(attrib, &tempsd, &err); + if (wres == DW_DLV_OK) { + snprintf(small_buf, sizeof(small_buf), "%lld", tempsd); + esb_append(esbp, small_buf); + } else if (wres == DW_DLV_NO_ENTRY) { + /* nothing? */ + } else { + print_error(dbg, "Cannot get formsdata..", wres, err); + } + break; + case DW_FORM_udata: + wres = dwarf_formudata(attrib, &tempud, &err); + if (wres == DW_DLV_OK) { + snprintf(small_buf, sizeof(small_buf), "%llu", tempud); + esb_append(esbp, small_buf); + } else if (wres == DW_DLV_NO_ENTRY) { + /* nothing? */ + } else { + print_error(dbg, "Cannot get formudata....", wres, err); + } + break; + case DW_FORM_string: + case DW_FORM_strp: + wres = dwarf_formstring(attrib, &temps, &err); + if (wres == DW_DLV_OK) { + esb_append(esbp, temps); + } else if (wres == DW_DLV_NO_ENTRY) { + /* nothing? */ + } else { + print_error(dbg, "Cannot get formstr/p....", wres, err); + } + + break; + case DW_FORM_flag: + wres = dwarf_formflag(attrib, &tempbool, &err); + if (wres == DW_DLV_OK) { + if (tempbool) { + snprintf(small_buf, sizeof(small_buf), "yes(%d)", + tempbool); + esb_append(esbp, small_buf); + } else { + snprintf(small_buf, sizeof(small_buf), "no"); + esb_append(esbp, small_buf); + } + } else if (wres == DW_DLV_NO_ENTRY) { + /* nothing? */ + } else { + print_error(dbg, "Cannot get formflag/p....", wres, err); + } + break; + case DW_FORM_indirect: + /* We should not ever get here, since the true form was + determined and direct_form has the DW_FORM_indirect if it is + used here in this attr. */ + esb_append(esbp, get_FORM_name(dbg, theform)); + break; + default: + print_error(dbg, "dwarf_whatform unexpected value", DW_DLV_OK, + err); + } + if (verbose && direct_form && direct_form == DW_FORM_indirect) { + char *form_indir = " (used DW_FORM_indirect) "; + + esb_append(esbp, form_indir); + } +} + +/* A cleanup so that when using a memory checker + we don't show irrelevant leftovers. +*/ +void +clean_up_die_esb() +{ + esb_destructor(&esb_base); +} + +#include "_tag_attr_table.c" + +static int +tag_attr_combination(Dwarf_Half tag, Dwarf_Half attr) +{ + if (attr > 0 && attr < 0x60) { + return ((tag_attr_combination_table[tag][attr / 0x20] + & (1 << (attr % 0x20))) > 0 ? TRUE : FALSE); + } else if (attr == DW_AT_MIPS_fde) { + /* no check now */ + return (TRUE); + } else + return (FALSE); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_frames.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_frames.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1104 @@ +/* + Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + + +$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_frames.c,v 1.5 2006/06/14 20:34:02 davea Exp $ */ + +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + + +#include "globals.h" + +#include "print_frames.h" +#include "dwconf.h" +#include "esb.h" + + +static void + print_one_frame_reg_col(Dwarf_Debug dbg, + Dwarf_Unsigned rule_id, + Dwarf_Small value_type, + Dwarf_Unsigned reg_used, + struct dwconf_s *config_data, + Dwarf_Signed offset_relevant, + Dwarf_Signed offset, Dwarf_Ptr block_ptr); + +/* + Gather the fde print logic here so the control logic + determining what FDE to print is clearer. +*/ +int +print_one_fde(Dwarf_Debug dbg, Dwarf_Fde fde, + Dwarf_Unsigned fde_index, + Dwarf_Cie * cie_data, + Dwarf_Signed cie_element_count, + Dwarf_Half address_size, int is_eh, + struct dwconf_s *config_data) +{ + Dwarf_Addr j = 0; + Dwarf_Addr low_pc = 0; + Dwarf_Unsigned func_length = 0; + Dwarf_Ptr fde_bytes = NULL; + Dwarf_Unsigned fde_bytes_length = 0; + Dwarf_Off cie_offset = 0; + Dwarf_Signed cie_index = 0; + Dwarf_Off fde_offset = 0; + Dwarf_Signed eh_table_offset = 0; + int fres = 0; + int offres = 0; + string temps = 0; + Dwarf_Error err = 0; + int printed_intro_addr = 0; + + fres = dwarf_get_fde_range(fde, + &low_pc, &func_length, + &fde_bytes, + &fde_bytes_length, + &cie_offset, &cie_index, + &fde_offset, &err); + if (fres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_get_fde_range", fres, err); + } + if (fres == DW_DLV_NO_ENTRY) { + return DW_DLV_NO_ENTRY; + } + if (cu_name_flag && + fde_offset_for_cu_low != DW_DLV_BADOFFSET && + (fde_offset < fde_offset_for_cu_low || + fde_offset > fde_offset_for_cu_high)) { + return DW_DLV_NO_ENTRY; + } + /* eh_table_offset is IRIX ONLY. */ + fres = dwarf_get_fde_exception_info(fde, &eh_table_offset, &err); + if (fres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_get_fde_exception_info", fres, err); + } + temps = get_fde_proc_name(dbg, low_pc); + printf + ("<%3lld><%#llx:%#llx><%s>", + cie_index, low_pc, (low_pc + func_length), + temps ? temps : "", fde_offset, fde_bytes_length); + + + if (!is_eh) { + /* IRIX uses eh_table_offset. */ + if (eh_table_offset == DW_DLX_NO_EH_OFFSET) { + printf("\n", "none"); + } else if (eh_table_offset == DW_DLX_EH_OFFSET_UNAVAILABLE) { + printf("\n", "unknown"); + } else { + printf("\n", eh_table_offset); + } + } else { + int ares = 0; + Dwarf_Small *data = 0; + Dwarf_Unsigned len = 0; + + ares = dwarf_get_fde_augmentation_data(fde, &data, &len, &err); + if (ares == DW_DLV_NO_ENTRY) { + /* do nothing. */ + } else if (ares == DW_DLV_OK) { + int k2; + + printf(""); + } /* else DW_DLV_ERROR, do nothing */ + printf("\n"); + } + /* call dwarf_get_fde_info_for_reg() to get whole matrix */ + + for (j = low_pc; j < low_pc + func_length; j++) { + Dwarf_Half k; + + if (config_data->cf_interface_number == 3) { + Dwarf_Signed reg = 0; + Dwarf_Signed offset_relevant = 0; + Dwarf_Small value_type = 0; + Dwarf_Signed offset_or_block_len = 0; + Dwarf_Signed offset = 0; + Dwarf_Ptr block_ptr = 0; + Dwarf_Addr row_pc = 0; + + int fires = dwarf_get_fde_info_for_cfa_reg3(fde, + j, + &value_type, + &offset_relevant, + ®, + &offset_or_block_len, + &block_ptr, + &row_pc, + &err); + + offset = offset_or_block_len; + if (fires == DW_DLV_ERROR) { + print_error(dbg, + "dwarf_get_fde_info_for_reg", fires, err); + } + if (fires == DW_DLV_NO_ENTRY) { + continue; + } + if (row_pc != j) { + /* duplicate row */ + continue; + } + if (!printed_intro_addr) { + printf(" %08llx:\t", j); + printed_intro_addr = 1; + } + print_one_frame_reg_col(dbg, config_data->cf_cfa_reg, + value_type, + reg, + config_data, + offset_relevant, offset, block_ptr); + } + for (k = 0; k < config_data->cf_table_entry_count; k++) { + Dwarf_Signed reg = 0; + Dwarf_Signed offset_relevant = 0; + int fires = 0; + Dwarf_Small value_type = 0; + Dwarf_Ptr block_ptr = 0; + Dwarf_Signed offset_or_block_len = 0; + Dwarf_Signed offset = 0; + Dwarf_Addr row_pc = 0; + + if (config_data->cf_interface_number == 3) { + + fires = dwarf_get_fde_info_for_reg3(fde, + k, + j, + &value_type, + &offset_relevant, + ®, + &offset_or_block_len, + &block_ptr, + &row_pc, &err); + offset = offset_or_block_len; + } else { /* ASSERT: + config_data->cf_interface_number == + 2 */ + + + value_type = DW_EXPR_OFFSET; + fires = dwarf_get_fde_info_for_reg(fde, + k, + j, + &offset_relevant, + ®, + &offset, &row_pc, + &err); + } + if (fires == DW_DLV_ERROR) { + printf("\n"); + print_error(dbg, + "dwarf_get_fde_info_for_reg", fires, err); + } + if (fires == DW_DLV_NO_ENTRY) { + continue; + } + if (row_pc != j) { + /* duplicate row */ + break; + } + if (!printed_intro_addr) { + printf(" %08llx:\t", j); + printed_intro_addr = 1; + } + print_one_frame_reg_col(dbg,k, + value_type, + reg, + config_data, + offset_relevant, offset, block_ptr); + + } + if (printed_intro_addr) { + printf("\n"); + printed_intro_addr = 0; + } + } + if (verbose > 1) { + Dwarf_Off fde_off; + Dwarf_Off cie_off; + + /* get the fde instructions and print them in raw form, just + like cie instructions */ + Dwarf_Ptr instrs; + Dwarf_Unsigned ilen; + int res; + + res = dwarf_get_fde_instr_bytes(fde, &instrs, &ilen, &err); + offres = + dwarf_fde_section_offset(dbg, fde, &fde_off, &cie_off, + &err); + if (offres == DW_DLV_OK) { + printf("\tfde sec. offset %llu 0x%llx" + " cie offset for fde: %llu 0x%llx\n", + (unsigned long long) fde_off, + (unsigned long long) fde_off, + (unsigned long long) cie_off, + (unsigned long long) cie_off); + + } + + + if (res == DW_DLV_OK) { + int cires = 0; + Dwarf_Unsigned cie_length = 0; + Dwarf_Small version = 0; + string augmenter; + Dwarf_Unsigned code_alignment_factor = 0; + Dwarf_Signed data_alignment_factor = 0; + Dwarf_Half return_address_register_rule = 0; + Dwarf_Ptr initial_instructions = 0; + Dwarf_Unsigned initial_instructions_length = 0; + + if (cie_index >= cie_element_count) { + printf("Bad cie index %lld with fde index %lld! " + "(table entry max %lld)\n", + (long long) cie_index, (long long) fde_index, + (long long) cie_element_count); + exit(1); + } + + cires = dwarf_get_cie_info(cie_data[cie_index], + &cie_length, + &version, + &augmenter, + &code_alignment_factor, + &data_alignment_factor, + &return_address_register_rule, + &initial_instructions, + &initial_instructions_length, + &err); + if (cires == DW_DLV_ERROR) { + printf + ("Bad cie index %lld with fde index %lld!\n", + (long long) cie_index, (long long) fde_index); + print_error(dbg, "dwarf_get_cie_info", cires, err); + } + if (cires == DW_DLV_NO_ENTRY) { + ; /* ? */ + } else { + + print_frame_inst_bytes(dbg, instrs, + (Dwarf_Signed) ilen, + data_alignment_factor, + (int) code_alignment_factor, + address_size, config_data); + } + } else if (res == DW_DLV_NO_ENTRY) { + printf + ("Impossible: no instr bytes for fde index %d?\n", + (int) fde_index); + } else { + /* DW_DLV_ERROR */ + printf + ("Error: on gettinginstr bytes for fde index %d?\n", + (int) fde_index); + print_error(dbg, "dwarf_get_fde_instr_bytes", res, err); + } + + } + return DW_DLV_OK; +} + + +/* Print a cie. Gather the print logic here so the + control logic deciding what to print + is clearer. +*/ +int +print_one_cie(Dwarf_Debug dbg, Dwarf_Cie cie, + Dwarf_Unsigned cie_index, Dwarf_Half address_size, + struct dwconf_s *config_data) +{ + + int cires = 0; + Dwarf_Unsigned cie_length = 0; + Dwarf_Small version = 0; + string augmenter = ""; + Dwarf_Unsigned code_alignment_factor = 0; + Dwarf_Signed data_alignment_factor = 0; + Dwarf_Half return_address_register_rule = 0; + Dwarf_Ptr initial_instructions = 0; + Dwarf_Unsigned initial_instructions_length = 0; + Dwarf_Off cie_off = 0; + Dwarf_Error err = 0; + + cires = dwarf_get_cie_info(cie, + &cie_length, + &version, + &augmenter, + &code_alignment_factor, + &data_alignment_factor, + &return_address_register_rule, + &initial_instructions, + &initial_instructions_length, &err); + if (cires == DW_DLV_ERROR) { + print_error(dbg, "dwarf_get_cie_info", cires, err); + } + if (cires == DW_DLV_NO_ENTRY) { + ; /* ? */ + printf("Impossible DW_DLV_NO_ENTRY on cie %d\n", + (int) cie_index); + return DW_DLV_NO_ENTRY; + } + { + printf("<%3lld>\tversion\t\t\t\t%d\n", cie_index, version); + cires = dwarf_cie_section_offset(dbg, cie, &cie_off, &err); + if (cires == DW_DLV_OK) { + printf("\tcie sec. offset %llu 0x%llx\n", + (unsigned long long) cie_off, + (unsigned long long) cie_off); + + } + + printf("\taugmentation\t\t\t%s\n", augmenter); + printf("\tcode_alignment_factor\t\t%llu\n", + (unsigned long long) code_alignment_factor); + printf("\tdata_alignment_factor\t\t%lld\n", + (long long) data_alignment_factor); + printf("\treturn_address_register\t\t%d\n", + (int) return_address_register_rule); + { + int ares = 0; + Dwarf_Small *data = 0; + Dwarf_Unsigned len = 0; + + ares = + dwarf_get_cie_augmentation_data(cie, &data, &len, &err); + if (ares == DW_DLV_NO_ENTRY) { + /* do nothing. */ + } else if (ares == DW_DLV_OK && len > 0) { + int k2; + + printf("\teh aug data len 0x%llx", (long long) len); + for (k2 = 0; data && k2 < len; ++k2) { + if (k2 == 0) { + printf(" bytes 0x"); + } + printf("%02x ", (unsigned char) data[k2]); + } + printf("\n"); + } /* else DW_DLV_ERROR or no data, do + nothing */ + } + + printf + ("\tbytes of initial instructions:\t%lld\n", + (long long) initial_instructions_length); + printf("\tcie length :\t\t\t%lld\n", (long long) cie_length); + print_frame_inst_bytes(dbg, initial_instructions, (Dwarf_Signed) + initial_instructions_length, + data_alignment_factor, + (int) code_alignment_factor, + address_size, config_data); + } + return DW_DLV_OK; +} + +void +get_string_from_locs(Dwarf_Debug dbg, + Dwarf_Ptr bytes_in, + Dwarf_Unsigned block_len,struct esb_s *out_string) +{ + + Dwarf_Locdesc *locdescarray = 0; + Dwarf_Signed listlen = 0; + Dwarf_Error err2 =0; + int skip_locdesc_header=1; + int res2 = dwarf_loclist_from_expr(dbg, + bytes_in,block_len, + &locdescarray, + &listlen,&err2); + if (res2 == DW_DLV_ERROR) { + print_error(dbg, "dwarf_get_loclist_from_expr", + res2, err2); + } + if(res2==DW_DLV_NO_ENTRY) { + return; + } + /* lcnt is always 1 */ + + /* Use locdescarray here.*/ + int res = dwarfdump_print_one_locdesc(dbg, + locdescarray, + skip_locdesc_header, + out_string); + if(res != DW_DLV_OK) { + printf("Bad status from _dwarf_print_one_locdesc %d\n",res); + exit(1); + } + + + + dwarf_dealloc(dbg, locdescarray->ld_s, DW_DLA_LOC_BLOCK); + dwarf_dealloc(dbg, locdescarray, DW_DLA_LOCDESC); + + + return ; +} + +/* Print the frame instructions in detail for a glob of instructions. +*/ + + /*ARGSUSED*/ void +print_frame_inst_bytes(Dwarf_Debug dbg, + Dwarf_Ptr cie_init_inst, Dwarf_Signed len, + Dwarf_Signed data_alignment_factor, + int code_alignment_factor, Dwarf_Half addr_size, + struct dwconf_s *config_data) +{ + unsigned char *instp = (unsigned char *) cie_init_inst; + Dwarf_Unsigned uval; + Dwarf_Unsigned uval2; + unsigned int uleblen; + unsigned int off = 0; + unsigned int loff = 0; + unsigned short u16; + unsigned int u32; + unsigned long long u64; + + for (; len > 0;) { + unsigned char ibyte = *instp; + int top = ibyte & 0xc0; + int bottom = ibyte & 0x3f; + int delta; + int reg; + + switch (top) { + case DW_CFA_advance_loc: + delta = ibyte & 0x3f; + printf("\t%2u DW_CFA_advance_loc %d", off, + (int) (delta * code_alignment_factor)); + if (verbose) { + printf(" (%d * %d)", (int) delta, + (int) code_alignment_factor); + } + printf("\n"); + break; + case DW_CFA_offset: + loff = off; + reg = ibyte & 0x3f; + uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + printf("\t%2u DW_CFA_offset ", loff); + printreg((Dwarf_Signed) reg, config_data); + printf(" %lld", (signed long long) + (((Dwarf_Signed) uval) * data_alignment_factor)); + if (verbose) { + printf(" (%llu * %d)", (unsigned long long) uval, + (int) data_alignment_factor); + } + printf("\n"); + break; + + case DW_CFA_restore: + reg = ibyte & 0x3f; + printf("\t%2u DW_CFA_restore \n", off); + printreg((Dwarf_Signed) reg, config_data); + printf("\n"); + break; + + default: + loff = off; + switch (bottom) { + case DW_CFA_set_loc: + /* operand is address, so need address size */ + /* which will be 4 or 8. */ + switch (addr_size) { + case 4: + { + __uint32_t v32; + + memcpy(&v32, instp + 1, addr_size); + uval = v32; + } + break; + case 8: + { + __uint64_t v64; + + memcpy(&v64, instp + 1, addr_size); + uval = v64; + } + break; + default: + printf + ("Error: Unexpected address size %d in DW_CFA_set_loc!\n", + addr_size); + uval = 0; + } + + instp += addr_size; + len -= (Dwarf_Signed) addr_size; + off += addr_size; + printf("\t%2u DW_CFA_set_loc %llu\n", + loff, (unsigned long long) uval); + break; + case DW_CFA_advance_loc1: + delta = (unsigned char) *(instp + 1); + uval2 = delta; + instp += 1; + len -= 1; + off += 1; + printf("\t%2u DW_CFA_advance_loc1 %llu\n", + loff, (unsigned long long) uval2); + break; + case DW_CFA_advance_loc2: + memcpy(&u16, instp + 1, 2); + uval2 = u16; + instp += 2; + len -= 2; + off += 2; + printf("\t%2u DW_CFA_advance_loc2 %llu\n", + loff, (unsigned long long) uval2); + break; + case DW_CFA_advance_loc4: + memcpy(&u32, instp + 1, 4); + uval2 = u32; + instp += 4; + len -= 4; + off += 4; + printf("\t%2u DW_CFA_advance_loc4 %llu\n", + loff, (unsigned long long) uval2); + break; + case DW_CFA_MIPS_advance_loc8: + memcpy(&u64, instp + 1, 8); + uval2 = u64; + instp += 8; + len -= 8; + off += 8; + printf("\t%2u DW_CFA_MIPS_advance_loc8 %llu\n", + loff, (unsigned long long) uval2); + break; + case DW_CFA_offset_extended: + uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + uval2 = + local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + printf("\t%2u DW_CFA_offset_extended ", loff); + printreg((Dwarf_Signed) uval, config_data); + printf(" %lld", (signed long long) + (((Dwarf_Signed) uval2) * + data_alignment_factor)); + if (verbose) { + printf(" (%llu * %d)", (unsigned long long) uval2, + (int) data_alignment_factor); + } + printf("\n"); + break; + + case DW_CFA_restore_extended: + uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + printf("\t%2u DW_CFA_restore_extended ", loff); + printreg((Dwarf_Signed) uval, config_data); + printf("\n"); + break; + case DW_CFA_undefined: + uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + printf("\t%2u DW_CFA_undefined ", loff); + printreg((Dwarf_Signed) uval, config_data); + printf("\n"); + break; + case DW_CFA_same_value: + uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + printf("\t%2u DW_CFA_same_value ", loff); + printreg((Dwarf_Signed) uval, config_data); + printf("\n"); + break; + case DW_CFA_register: + uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + uval2 = + local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + printf("\t%2u DW_CFA_register ", loff); + printreg((Dwarf_Signed) uval, config_data); + printf(" = "); + printreg((Dwarf_Signed) uval2, config_data); + printf("\n"); + break; + case DW_CFA_remember_state: + printf("\t%2u DW_CFA_remember_state\n", loff); + break; + case DW_CFA_restore_state: + printf("\t%2u DW_CFA_restore_state\n", loff); + break; + case DW_CFA_def_cfa: + uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + uval2 = + local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + printf("\t%2u DW_CFA_def_cfa ", loff); + printreg((Dwarf_Signed) uval, config_data); + printf(" %llu", (unsigned long long) uval2); + printf("\n"); + break; + case DW_CFA_def_cfa_register: + uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + printf("\t%2u DW_CFA_def_cfa_register ", loff); + printreg((Dwarf_Signed) uval, config_data); + printf("\n"); + break; + case DW_CFA_def_cfa_offset: + uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + printf("\t%2u DW_CFA_def_cfa_offset %llu\n", + loff, (unsigned long long) uval); + break; + + case DW_CFA_nop: + printf("\t%2u DW_CFA_nop\n", loff); + break; + + case DW_CFA_def_cfa_expression: /* DWARF3 */ + { + Dwarf_Unsigned block_len = + local_dwarf_decode_u_leb128(instp + 1, + &uleblen); + + instp += uleblen; + len -= uleblen; + off += uleblen; + printf + ("\t%2u DW_CFA_def_cfa_expression expr block len %lld\n", + loff, (unsigned long long) + block_len); + dump_block("\t\t", (char *) instp+1, + (Dwarf_Signed) block_len); + printf("\n"); + if(verbose) { + struct esb_s exprstring; + esb_constructor(&exprstring); + get_string_from_locs(dbg, + instp+1,block_len,&exprstring); + printf("\t\t%s\n",esb_get_string(&exprstring)); + esb_destructor(&exprstring); + } + instp += block_len; + len -= block_len; + off += block_len; + } + break; + case DW_CFA_expression: /* DWARF3 */ + uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + { + /* instp is always 1 byte back, so we need +1 + when we use it. See the final increment + of this for loop. */ + Dwarf_Unsigned block_len = + local_dwarf_decode_u_leb128(instp + 1, + &uleblen); + + instp += uleblen; + len -= uleblen; + off += uleblen; + printf + ("\t%2u DW_CFA_expression %llu expr block len %lld\n", + loff, (unsigned long long) uval, + (unsigned long long) + block_len); + dump_block("\t\t", (char *) instp+1, + (Dwarf_Signed) block_len); + printf("\n"); + if(verbose) { + struct esb_s exprstring; + esb_constructor(&exprstring); + get_string_from_locs(dbg, + instp+1,block_len,&exprstring); + printf("\t\t%s\n",esb_get_string(&exprstring)); + esb_destructor(&exprstring); + } + instp += block_len; + len -= block_len; + off += block_len; + } + + break; + case DW_CFA_cfa_offset_extended_sf: /* DWARF3 */ + uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + { + /* instp is always 1 byte back, so we need +1 + when we use it. See the final increment + of this for loop. */ + Dwarf_Signed sval2 = + local_dwarf_decode_s_leb128(instp + 1, + &uleblen); + + instp += uleblen; + len -= uleblen; + off += uleblen; + printf("\t%2u DW_CFA_offset_extended_sf ", loff); + printreg((Dwarf_Signed) uval, config_data); + printf(" %lld", (signed long long) + ((sval2) * data_alignment_factor)); + if (verbose) { + printf(" (%lld * %d)", (long long) sval2, + (int) data_alignment_factor); + } + } + printf("\n"); + break; + case DW_CFA_def_cfa_sf: /* DWARF3 */ + /* instp is always 1 byte back, so we need +1 + when we use it. See the final increment + of this for loop. */ + uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + { + Dwarf_Signed sval2 = + local_dwarf_decode_s_leb128(instp + 1, + &uleblen); + + instp += uleblen; + len -= uleblen; + off += uleblen; + printf("\t%2u DW_CFA_def_cfa_sf ", loff); + printreg((Dwarf_Signed) uval, config_data); + printf(" %lld", (long long) sval2); + printf(" (*data alignment factor=>%lld)", + (long long)(sval2*data_alignment_factor)); + } + printf("\n"); + break; + case DW_CFA_def_cfa_offset_sf: /* DWARF3 */ + { + /* instp is always 1 byte back, so we need +1 + when we use it. See the final increment + of this for loop. */ + Dwarf_Signed sval = + local_dwarf_decode_s_leb128(instp + 1, + &uleblen); + + instp += uleblen; + len -= uleblen; + off += uleblen; + printf("\t%2u DW_CFA_def_cfa_offset_sf %lld (*data alignment factor=> %lld)\n", + loff, (long long) sval, + (long long)(data_alignment_factor*sval)); + + } + break; + case DW_CFA_val_offset: /* DWARF3 */ + /* instp is always 1 byte back, so we need +1 + when we use it. See the final increment + of this for loop. */ + uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + { + uval2 = + local_dwarf_decode_s_leb128(instp + 1, + &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + printf("\t%2u DW_CFA_val_offset ", loff); + printreg((Dwarf_Signed) uval, config_data); + printf(" %lld", (unsigned long long) + (((Dwarf_Signed) uval2) * + data_alignment_factor)); + if (verbose) { + printf(" (%lld * %d)", (long long) uval2, + (int) data_alignment_factor); + } + } + printf("\n"); + + break; + case DW_CFA_val_offset_sf: /* DWARF3 */ + /* instp is always 1 byte back, so we need +1 + when we use it. See the final increment + of this for loop. */ + uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + { + Dwarf_Signed sval2 = + local_dwarf_decode_s_leb128(instp + 1, + &uleblen); + + instp += uleblen; + len -= uleblen; + off += uleblen; + printf("\t%2u DW_CFA_val_offset_sf ", loff); + printreg((Dwarf_Signed) uval, config_data); + printf(" %lld", (signed long long) + ((sval2) * data_alignment_factor)); + if (verbose) { + printf(" (%lld * %d)", (long long) sval2, + (int) data_alignment_factor); + } + } + printf("\n"); + + break; + case DW_CFA_val_expression: /* DWARF3 */ + /* instp is always 1 byte back, so we need +1 + when we use it. See the final increment + of this for loop. */ + uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen); + instp += uleblen; + len -= uleblen; + off += uleblen; + { + Dwarf_Unsigned block_len = + local_dwarf_decode_u_leb128(instp + 1, + &uleblen); + + instp += uleblen; + len -= uleblen; + off += uleblen; + printf + ("\t%2u DW_CFA_val_expression %llu expr block len %lld\n", + loff, (unsigned long long) uval, + (unsigned long long) + block_len); + dump_block("\t\t", (char *) instp+1, + (Dwarf_Signed) block_len); + printf("\n"); + if(verbose) { + struct esb_s exprstring; + esb_constructor(&exprstring); + get_string_from_locs(dbg, + instp+1,block_len,&exprstring); + printf("\t\t%s\n",esb_get_string(&exprstring)); + esb_destructor(&exprstring); + } + instp += block_len; + len -= block_len; + off += block_len; + } + + + break; + + +#ifdef DW_CFA_GNU_window_save + case DW_CFA_GNU_window_save:{ + /* no information: this just tells unwinder to + restore the window registers from the previous + frame's window save area */ + printf("\t%2u DW_CFA_GNU_window_save \n", loff); + break; + } +#endif +#ifdef DW_CFA_GNU_negative_offset_extended + case DW_CFA_GNU_negative_offset_extended:{ + printf + ("\t%2u DW_CFA_GNU_negative_offset_extended \n", + loff); + } +#endif +#ifdef DW_CFA_GNU_args_size + /* single uleb128 is the current arg area size in + bytes. no register exists yet to save this in */ + case DW_CFA_GNU_args_size:{ + Dwarf_Unsigned lreg; + + /* instp is always 1 byte back, so we need +1 + when we use it. See the final increment + of this for loop. */ + lreg = + local_dwarf_decode_u_leb128(instp + 1, + &uleblen); + printf + ("\t%2u DW_CFA_GNU_args_size arg size: %llu\n", + loff, (unsigned long long) lreg); + instp += uleblen; + len -= uleblen; + off += uleblen; + + break; + } +#endif + + default: + printf("\t%u Unexpected op 0x%x: \n", + loff, (unsigned int) bottom); + len = 0; + break; + } + } + instp++; + len--; + off++; + } +} + +/* Print our register names for the cases we have a name. + Delegate to the configure code to actually do the print. +*/ +void +printreg(Dwarf_Signed reg, struct dwconf_s *config_data) +{ + print_reg_from_config_data(reg, config_data); +} + + +/* + Actually does the printing of a rule in the table. + This may print something or may print nothing! +*/ + +static void +print_one_frame_reg_col(Dwarf_Debug dbg, + Dwarf_Unsigned rule_id, + Dwarf_Small value_type, + Dwarf_Unsigned reg_used, + struct dwconf_s *config_data, + Dwarf_Signed offset_relevant, + Dwarf_Signed offset, + Dwarf_Ptr block_ptr) +{ + char *type_title = ""; + int print_type_title = 1; + + if (config_data->cf_interface_number == 2) + print_type_title = 0; + + switch (value_type) { + case DW_EXPR_OFFSET: + type_title = "off"; + goto preg2; + case DW_EXPR_VAL_OFFSET: + type_title = "valoff"; + preg2: + if (reg_used == config_data->cf_initial_rule_value) { + break; + } + if (print_type_title) + printf("<%s ", type_title); + printreg((Dwarf_Signed) rule_id, config_data); + printf("="); + if (offset_relevant == 0) { + printreg((Dwarf_Signed) reg_used, config_data); + printf(" "); + } else { + printf("%02lld", offset); + printf("("); + printreg((Dwarf_Signed) reg_used, config_data); + printf(") "); + } + if (print_type_title) + printf("%s", "> "); + break; + case DW_EXPR_EXPRESSION: + type_title = "expr"; + goto pexp2; + case DW_EXPR_VAL_EXPRESSION: + type_title = "valexpr"; + pexp2: + if (print_type_title) + printf("<%s ", type_title); + printreg((Dwarf_Signed) rule_id, config_data); + printf("="); + printf("expr-block-len=%lld", (long long) offset); + if (print_type_title) + printf("%s", "> "); + if (verbose) { + char pref[40]; + + strcpy(pref, "<"); + strcat(pref, type_title); + strcat(pref, "bytes:"); + dump_block(pref, block_ptr, offset); + printf("%s", "> "); + if(verbose) { + struct esb_s exprstring; + esb_constructor(&exprstring); + get_string_from_locs(dbg, + block_ptr,offset,&exprstring); + printf("",esb_get_string(&exprstring)); + esb_destructor(&exprstring); + } + } + break; + default: + printf("Internal error in libdwarf, value type %d\n", + value_type); + exit(1); + } + return; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_frames.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_frames.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,49 @@ +/* + Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + + +$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_frames.h,v 1.2 2006/04/17 00:09:56 davea Exp $ */ + +int + print_one_fde(Dwarf_Debug dbg, Dwarf_Fde fde, + Dwarf_Unsigned fde_index, + Dwarf_Cie * cie_data, + Dwarf_Signed cie_element_count, + Dwarf_Half address_size, + int is_eh, + struct dwconf_s * config_data); + +int + print_one_cie(Dwarf_Debug dbg, Dwarf_Cie cie, + Dwarf_Unsigned cie_index, + Dwarf_Half address_size, + struct dwconf_s * config_data); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_reloc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_reloc.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,512 @@ +/* + Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + + +$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_reloc.c,v 1.11 2005/08/04 05:09:37 davea Exp $ */ + +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + + + +#include "globals.h" + + +#define DW_SECTION_REL_DEBUG_INFO 0 +#define DW_SECTION_REL_DEBUG_LINE 1 +#define DW_SECTION_REL_DEBUG_PUBNAME 2 +#define DW_SECTION_REL_DEBUG_ABBREV 3 +#define DW_SECTION_REL_DEBUG_ARANGES 4 +#define DW_SECTION_REL_DEBUG_FRAME 5 +#define DW_SECTION_REL_DEBUG_NUM 6 + +#define DW_SECTNAME_REL_DEBUG_INFO ".rel.debug_info" +#define DW_SECTNAME_REL_DEBUG_LINE ".rel.debug_line" +#define DW_SECTNAME_REL_DEBUG_PUBNAME ".rel.debug_pubname" +#define DW_SECTNAME_REL_DEBUG_ABBREV ".rel.debug_abbrev" +#define DW_SECTNAME_REL_DEBUG_ARANGES ".rel.debug_aranges" +#define DW_SECTNAME_REL_DEBUG_FRAME ".rel.debug_frame" + +#define STRING_FOR_DUPLICATE " duplicate" +#define STRING_FOR_NULL " null" + +static char *sectnames[] = { + DW_SECTNAME_REL_DEBUG_INFO, + DW_SECTNAME_REL_DEBUG_LINE, + DW_SECTNAME_REL_DEBUG_PUBNAME, + DW_SECTNAME_REL_DEBUG_ABBREV, + DW_SECTNAME_REL_DEBUG_ARANGES, + DW_SECTNAME_REL_DEBUG_FRAME, +}; + +static char *error_msg_duplicate[] = { + DW_SECTNAME_REL_DEBUG_INFO STRING_FOR_DUPLICATE, + DW_SECTNAME_REL_DEBUG_LINE STRING_FOR_DUPLICATE, + DW_SECTNAME_REL_DEBUG_PUBNAME STRING_FOR_DUPLICATE, + DW_SECTNAME_REL_DEBUG_ABBREV STRING_FOR_DUPLICATE, + DW_SECTNAME_REL_DEBUG_ARANGES STRING_FOR_DUPLICATE, + DW_SECTNAME_REL_DEBUG_FRAME STRING_FOR_DUPLICATE, +}; + +static char *error_msg_null[] = { + DW_SECTNAME_REL_DEBUG_INFO STRING_FOR_NULL, + DW_SECTNAME_REL_DEBUG_LINE STRING_FOR_NULL, + DW_SECTNAME_REL_DEBUG_PUBNAME STRING_FOR_NULL, + DW_SECTNAME_REL_DEBUG_ABBREV STRING_FOR_NULL, + DW_SECTNAME_REL_DEBUG_ARANGES STRING_FOR_NULL, + DW_SECTNAME_REL_DEBUG_FRAME STRING_FOR_NULL, +}; + +#define SECT_DATA_SET(x) { \ + if (sect_data[(x)].buf != NULL) { \ + print_error(dbg, error_msg_duplicate[(x)],DW_DLV_OK, err); \ + } \ + if ((data = elf_getdata(scn, 0)) == NULL || data->d_size == 0) { \ + print_error(dbg, error_msg_null[(x)],DW_DLV_OK, err); \ + } \ + sect_data[(x)].buf = data -> d_buf; \ + sect_data[(x)].size = data -> d_size; \ + } + +static char *reloc_type_names[] = { + "R_MIPS_NONE", "R_MIPS_16", "R_MIPS_32", "R_MIPS_REL32", + "R_MIPS_26", "R_MIPS_HI16", "R_MIPS_LO16", "R_MIPS_GPREL16", + "R_MIPS_LITERAL", "R_MIPS_GOT16", "R_MIPS_PC16", "R_MIPS_CALL16", + "R_MIPS_GPREL32", /* 12 */ + "reloc type 13?", "reloc type 14?", "reloc type 15?", + "R_MIPS_SHIFT5", /* 16 */ + "R_MIPS_SHIFT6", /* 17 */ + "R_MIPS_64", /* 18 */ + "R_MIPS_GOT_DISP", /* 19 */ + "R_MIPS_GOT_PAGE", /* 20 */ + "R_MIPS_GOT_OFST", /* 21 */ + "R_MIPS_GOT_HI16", /* 22 */ + "R_MIPS_GOT_LO16", /* 23 */ + "R_MIPS_SUB", /* 24 */ + "R_MIPS_INSERT_A", /* 25 */ + "R_MIPS_INSERT_B", /* 26 */ + "R_MIPS_DELETE", /* 27 */ + "R_MIPS_HIGHER", /* 28 */ + "R_MIPS_HIGHEST", /* 29 */ + "R_MIPS_CALL_HI16", /* 30 */ + "R_MIPS_CALL_LO16", /* 31 */ + "R_MIPS_SCN_DISP", /* 32 */ + "R_MIPS_REL16", /* 33 */ + "R_MIPS_ADD_IMMEDIATE", /* 34 */ +}; + +/* + return valid reloc type names. + if buf is used, it is static, so beware it + will be overrwritten by the next call. +*/ +static char * +get_reloc_type_names(int index) +{ + static char buf[100]; + int arysiz = sizeof(reloc_type_names) / sizeof(char *); + char *retval; + + if (index < 0 || index >= arysiz) { + sprintf(buf, "reloc type %d unknown", (int) index); + retval = buf; + } else { + retval = reloc_type_names[index]; + } + return retval; +} + + +static struct { + Dwarf_Small *buf; + Dwarf_Unsigned size; +} sect_data[DW_SECTION_REL_DEBUG_NUM]; + +#ifndef HAVE_ELF64_GETEHDR +#define Elf64_Addr long +#define Elf64_Word unsigned long +#define Elf64_Xword unsigned long +#define Elf64_Sym long +#endif + +typedef size_t indx_type; + +typedef struct { + indx_type indx; + char *name; + Elf32_Addr value; + Elf32_Word size; + int type; + int bind; + unsigned char other; + Elf32_Half shndx; +} SYM; + + +typedef struct { + indx_type indx; + char *name; + Elf64_Addr value; + Elf64_Xword size; + int type; + int bind; + unsigned char other; + unsigned short shndx; +} SYM64; + +static void print_reloc_information_64(int section_no, + Dwarf_Small * buf, + Dwarf_Unsigned size); +static void print_reloc_information_32(int section_no, + Dwarf_Small * buf, + Dwarf_Unsigned size); +static SYM *readsyms(Elf32_Sym * data, size_t num, Elf * elf, + Elf32_Word link); +static SYM64 *read_64_syms(Elf64_Sym * data, size_t num, Elf * elf, + Elf64_Word link); +static void *get_scndata(Elf_Scn * fd_scn, size_t * scn_size); +static void print_relocinfo_64(Dwarf_Debug dbg, Elf * elf); +static void print_relocinfo_32(Dwarf_Debug dbg, Elf * elf); + +static SYM *sym_data; +static SYM64 *sym_data_64; + +void +print_relocinfo(Dwarf_Debug dbg) +{ + Elf *elf; + char *endr_ident; + int is_64bit; + int res; + int i; + Elf32_Sym *sym = 0; + + for (i = 0; i < DW_SECTION_REL_DEBUG_NUM; i++) { + sect_data[i].buf = 0; + sect_data[i].size = 0; + } + res = dwarf_get_elf(dbg, &elf, &err); + if (res != DW_DLV_OK) { + print_error(dbg, "dwarf_get_elf error", res, err); + } + if ((endr_ident = elf_getident(elf, NULL)) == NULL) { + print_error(dbg, "DW_ELF_GETIDENT_ERROR", res, err); + } + is_64bit = (endr_ident[EI_CLASS] == ELFCLASS64); + if (is_64bit) { + print_relocinfo_64(dbg, elf); + } else { + print_relocinfo_32(dbg, elf); + } +} + +static void +print_relocinfo_64(Dwarf_Debug dbg, Elf * elf) +{ +#ifdef HAVE_ELF64_GETEHDR + Elf_Scn *scn = NULL; + Elf_Data *data; + Elf64_Ehdr *ehdr64; + Elf64_Shdr *shdr64; + char *scn_name; + int i; + Elf64_Sym *sym_64 = 0; + + if ((ehdr64 = elf64_getehdr(elf)) == NULL) { + print_error(dbg, "DW_ELF_GETEHDR_ERROR", DW_DLV_OK, err); + } + + while ((scn = elf_nextscn(elf, scn)) != NULL) { + + if ((shdr64 = elf64_getshdr(scn)) == NULL) { + print_error(dbg, "DW_ELF_GETSHDR_ERROR", DW_DLV_OK, err); + } + if ((scn_name = + elf_strptr(elf, ehdr64->e_shstrndx, shdr64->sh_name)) + == NULL) { + print_error(dbg, "DW_ELF_STRPTR_ERROR", DW_DLV_OK, err); + } + if (shdr64->sh_type == SHT_SYMTAB) { + size_t sym_size = 0; + size_t count = 0; + + if ((sym_64 = + (Elf64_Sym *) get_scndata(scn, &sym_size)) == NULL) { + print_error(dbg, "no symbol table data", DW_DLV_OK, + err); + } + count = sym_size / sizeof(Elf64_Sym); + sym_64++; + free(sym_data_64); + sym_data_64 = read_64_syms(sym_64, count, elf, shdr64->sh_link); + if (sym_data_64 == NULL) { + print_error(dbg, "problem reading symbol table data", + DW_DLV_OK, err); + } + } else if (strncmp(scn_name, ".rel.debug_", 11)) + continue; + else if (strcmp(scn_name, ".rel.debug_info") == 0) { + SECT_DATA_SET(DW_SECTION_REL_DEBUG_INFO) + } else if (strcmp(scn_name, ".rel.debug_line") == 0) { + SECT_DATA_SET(DW_SECTION_REL_DEBUG_LINE) + } else if (strcmp(scn_name, ".rel.debug_pubname") == 0) { + SECT_DATA_SET(DW_SECTION_REL_DEBUG_PUBNAME) + } else if (strcmp(scn_name, ".rel.debug_aranges") == 0) { + SECT_DATA_SET(DW_SECTION_REL_DEBUG_ARANGES) + } else if (strcmp(scn_name, ".rel.debug_abbrev") == 0) { + SECT_DATA_SET(DW_SECTION_REL_DEBUG_ABBREV) + } else if (strcmp(scn_name, ".rel.debug_frame") == 0) { + SECT_DATA_SET(DW_SECTION_REL_DEBUG_FRAME) + } + } /* while */ + + for (i = 0; i < DW_SECTION_REL_DEBUG_NUM; i++) { + if (sect_data[i].buf != NULL && sect_data[i].size > 0) { + print_reloc_information_64(i, sect_data[i].buf, + sect_data[i].size); + } + } +#endif +} + +static void +print_relocinfo_32(Dwarf_Debug dbg, Elf * elf) +{ + Elf_Scn *scn = NULL; + Elf_Data *data; + Elf32_Ehdr *ehdr32; + Elf32_Shdr *shdr32; + char *scn_name; + int i; + Elf32_Sym *sym = 0; + + if ((ehdr32 = elf32_getehdr(elf)) == NULL) { + print_error(dbg, "DW_ELF_GETEHDR_ERROR", DW_DLV_OK, err); + } + while ((scn = elf_nextscn(elf, scn)) != NULL) { + if ((shdr32 = elf32_getshdr(scn)) == NULL) { + print_error(dbg, "DW_ELF_GETSHDR_ERROR", DW_DLV_OK, err); + } + if ((scn_name = + elf_strptr(elf, ehdr32->e_shstrndx, shdr32->sh_name) + ) == NULL) { + print_error(dbg, "DW_ELF_STRPTR_ERROR", DW_DLV_OK, err); + } + if (shdr32->sh_type == SHT_SYMTAB) { + size_t sym_size = 0; + size_t count = 0; + + if ((sym = + (Elf32_Sym *) get_scndata(scn, &sym_size)) == NULL) { + print_error(dbg, "no symbol table data", DW_DLV_OK, + err); + } + sym = (Elf32_Sym *) get_scndata(scn, &sym_size); + count = sym_size / sizeof(Elf32_Sym); + sym++; + free(sym_data); + sym_data = readsyms(sym, count, elf, shdr32->sh_link); + if (sym_data == NULL) { + print_error(dbg, "problem reading symbol table data", + DW_DLV_OK, err); + } + } else if (strncmp(scn_name, ".rel.debug_", 11)) + continue; + else if (strcmp(scn_name, ".rel.debug_info") == 0) { + SECT_DATA_SET(DW_SECTION_REL_DEBUG_INFO) + } else if (strcmp(scn_name, ".rel.debug_line") == 0) { + SECT_DATA_SET(DW_SECTION_REL_DEBUG_LINE) + } else if (strcmp(scn_name, ".rel.debug_pubname") == 0) { + SECT_DATA_SET(DW_SECTION_REL_DEBUG_PUBNAME) + } else if (strcmp(scn_name, ".rel.debug_aranges") == 0) { + SECT_DATA_SET(DW_SECTION_REL_DEBUG_ARANGES) + } else if (strcmp(scn_name, ".rel.debug_abbrev") == 0) { + SECT_DATA_SET(DW_SECTION_REL_DEBUG_ABBREV) + } else if (strcmp(scn_name, ".rel.debug_frame") == 0) { + SECT_DATA_SET(DW_SECTION_REL_DEBUG_FRAME) + } + } /* while */ + + for (i = 0; i < DW_SECTION_REL_DEBUG_NUM; i++) { + if (sect_data[i].buf != NULL && sect_data[i].size > 0) { + print_reloc_information_32(i, sect_data[i].buf, + sect_data[i].size); + } + } +} + +#if HAVE_ELF64_R_INFO +#ifndef ELF64_R_TYPE +#define ELF64_R_TYPE(x) 0 /* FIXME */ +#endif +#ifndef ELF64_R_SYM +#define ELF64_R_SYM(x) 0 /* FIXME */ +#endif +#ifndef ELF64_ST_TYPE +#define ELF64_ST_TYPE(x) 0 /* FIXME */ +#endif +#ifndef ELF64_ST_BIND +#define ELF64_ST_BIND(x) 0 /* FIXME */ +#endif +#endif /* HAVE_ELF64_R_INFO */ + + +static void +print_reloc_information_64(int section_no, Dwarf_Small * buf, + Dwarf_Unsigned size) +{ + Dwarf_Unsigned off; + + printf("\n%s:\n", sectnames[section_no]); +#if HAVE_ELF64_GETEHDR + for (off = 0; off < size; off += sizeof(Elf64_Rel)) { +#if HAVE_ELF64_R_INFO + /* This works for the Elf64_Rel in linux */ + Elf64_Rel *p = (Elf64_Rel *) (buf + off); + + printf("%5lu\t<%3ld> %-34s%s\n", + (unsigned long int) (p->r_offset), + (long)ELF64_R_SYM(p->r_info), + sym_data[ELF64_R_SYM(p->r_info) - 1].name, + get_reloc_type_names(ELF64_R_TYPE(p->r_info))); +#else + /* sgi/mips -64 does not have r_info in the 64bit relocations, + but seperate fields, with 3 types, actually. Only one of + which prints here, as only one really used with dwarf */ + Elf64_Rel *p = (Elf64_Rel *) (buf + off); + + printf("%5llu\t<%3d> %-34s%s\n", + (unsigned long long int) (p->r_offset), + (long)p->r_sym, sym_data_64[p->r_sym - 1].name, + get_reloc_type_names(p->r_type)); +#endif + } +#endif /* HAVE_ELF64_GETEHDR */ +} + +static void +print_reloc_information_32(int section_no, Dwarf_Small * buf, + Dwarf_Unsigned size) +{ + Dwarf_Unsigned off; + + printf("\n%s:\n", sectnames[section_no]); + for (off = 0; off < size; off += sizeof(Elf32_Rel)) { + Elf32_Rel *p = (Elf32_Rel *) (buf + off); + + printf("%5lu\t<%3d> %-34s%s\n", + (unsigned long int) (p->r_offset), + ELF32_R_SYM(p->r_info), + sym_data[ELF32_R_SYM(p->r_info) - 1].name, + get_reloc_type_names(ELF32_R_TYPE(p->r_info))); + } +} + +static SYM * +readsyms(Elf32_Sym * data, size_t num, Elf * elf, Elf32_Word link) +{ + SYM *s, *buf; + indx_type i; + + if ((buf = (SYM *) calloc(num, sizeof(SYM))) == NULL) { + return NULL; + } + s = buf; /* save pointer to head of array */ + for (i = 1; i < num; i++, data++, buf++) { + buf->indx = i; + buf->name = (char *) elf_strptr(elf, link, data->st_name); + buf->value = data->st_value; + buf->size = data->st_size; + buf->type = ELF32_ST_TYPE(data->st_info); + buf->bind = ELF32_ST_BIND(data->st_info); + buf->other = data->st_other; + buf->shndx = data->st_shndx; + } /* end for loop */ + return (s); +} + +static SYM64 * +read_64_syms(Elf64_Sym * data, size_t num, Elf * elf, Elf64_Word link) +{ +#ifdef HAVE_ELF64_GETEHDR + + SYM64 *s, *buf; + indx_type i; + + if ((buf = (SYM64 *) calloc(num, sizeof(SYM64))) == NULL) { + return NULL; + } + s = buf; /* save pointer to head of array */ + for (i = 1; i < num; i++, data++, buf++) { + buf->indx = i; + buf->name = (char *) elf_strptr(elf, link, data->st_name); + buf->value = data->st_value; + buf->size = data->st_size; + buf->type = ELF64_ST_TYPE(data->st_info); + buf->bind = ELF64_ST_BIND(data->st_info); + buf->other = data->st_other; + buf->shndx = data->st_shndx; + } /* end for loop */ + return (s); +#else + return 0; +#endif /* HAVE_ELF64_GETEHDR */ +} + +static void * +get_scndata(Elf_Scn * fd_scn, size_t * scn_size) +{ + Elf_Data *p_data; + + p_data = 0; + if ((p_data = elf_getdata(fd_scn, p_data)) == 0 || + p_data->d_size == 0) { + return NULL; + } + *scn_size = p_data->d_size; + return (p_data->d_buf); +} + +/* Cleanup of malloc space (some of the pointers will be 0 here) + so dwarfdump looks 'clean' to a malloc checker. +*/ +void +clean_up_syms_malloc_data() +{ + free(sym_data); + free(sym_data_64); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_sections.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_sections.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1758 @@ +/* + Copyright (C) 2000,2003,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + + +$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_sections.c,v 1.69 2006/04/17 00:09:56 davea Exp $ */ +#include "globals.h" +#include "dwarf_names.h" +#include "dwconf.h" + +#include "print_frames.h" +/* + * Print line number information: + * filename + * new basic-block + * [line] [address] + */ + + +static void + print_pubname_style_entry(Dwarf_Debug dbg, + char *line_title, + char *name, + Dwarf_Unsigned die_off, + Dwarf_Unsigned cu_off, + Dwarf_Unsigned global_cu_off, + Dwarf_Unsigned maxoff); + + +/* referred in dwarfdump.c */ +Dwarf_Die current_cu_die_for_print_frames; + +/* If an offset is bad, libdwarf will notice it and + return an error. + If it does the error checking in + print_pubname_style_entry() + will be useless as we give up here on an error. + + This intended for checking pubnames-style call return + values (for all the pubnames-style interfaces). + + In at least one gigantic executable die_off turned out wrong. +*/ + +static void +deal_with_name_offset_err(Dwarf_Debug dbg, + char *err_loc, + char *name, Dwarf_Unsigned die_off, + int nres, Dwarf_Error err) +{ + if (nres == DW_DLV_ERROR) { + Dwarf_Unsigned myerr = dwarf_errno(err); + + if (myerr == DW_DLE_OFFSET_BAD) { + printf("Error: bad offset %s, %s %lld (0x%llx)\n", + err_loc, + name, + (long long) die_off, (unsigned long long) die_off); + } + print_error(dbg, err_loc, nres, err); + } +} + +static void +print_source_intro(Dwarf_Die cu_die) +{ + Dwarf_Off off = 0; + int ores = dwarf_dieoffset(cu_die, &off, &err); + + if (ores == DW_DLV_OK) { + printf + ("Source lines (from CU-DIE at .debug_info offset %llu):\n", + (unsigned long long) off); + } else { + printf("Source lines (for the CU-DIE at unknown location):\n"); + } +} + + +extern void +print_line_numbers_this_cu(Dwarf_Debug dbg, Dwarf_Die cu_die) +{ + Dwarf_Signed linecount = 0; + Dwarf_Line *linebuf = NULL; + Dwarf_Signed i = 0; + Dwarf_Addr pc = 0; + Dwarf_Unsigned lineno = 0; + Dwarf_Signed column = 0; + string filename; + Dwarf_Bool newstatement = 0; + Dwarf_Bool lineendsequence = 0; + Dwarf_Bool new_basic_block = 0; + int lres = 0; + int sres = 0; + int ares = 0; + int lires = 0; + int cores = 0; + + printf("\n.debug_line: line number info for a single cu\n"); + if (verbose > 1) { + print_source_intro(cu_die); + print_one_die(dbg, cu_die, /* print_information= */ 1, + /* srcfiles= */ 0, /* cnt= */ 0); + + lres = dwarf_print_lines(cu_die, &err); + if (lres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_srclines details", lres, err); + } + return; + } + lres = dwarf_srclines(cu_die, &linebuf, &linecount, &err); + if (lres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_srclines", lres, err); + } else if (lres == DW_DLV_NO_ENTRY) { + /* no line information is included */ + } else { + print_source_intro(cu_die); + if (verbose) { + print_one_die(dbg, cu_die, /* print_information= */ 1, + /* srcfiles= */ 0, /* cnt= */ 0); + } + printf + ("\t[row,column]\t\t//= (outlen - 1)) { + strncpy(out, in, outlen - 1); + out[outlen - 1] = 0; + } else { + strcpy(out, in); + } +} + +/* + Returns 1 if a proc with this low_pc found. + Else returns 0. + + +*/ +static int +get_proc_name(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc, + char *proc_name_buf, int proc_name_buf_len) +{ + Dwarf_Signed atcnt = 0; + Dwarf_Signed i = 0; + Dwarf_Attribute *atlist = NULL; + Dwarf_Addr low_pc_die = 0; + int atres = 0; + int funcres = 1; + int funcpcfound = 0; + int funcnamefound = 1; + + proc_name_buf[0] = 0; /* always set to something */ + atres = dwarf_attrlist(die, &atlist, &atcnt, &err); + if (atres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_attrlist", atres, err); + return 0; + } + if (atres == DW_DLV_NO_ENTRY) { + return 0; + } + for (i = 0; i < atcnt; i++) { + Dwarf_Half attr; + int ares; + string temps; + int sres; + int dres; + + if (funcnamefound == 1 && funcpcfound == 1) { + /* stop as soon as both found */ + break; + } + ares = dwarf_whatattr(atlist[i], &attr, &err); + if (ares == DW_DLV_ERROR) { + print_error(dbg, "get_proc_name whatattr error", ares, err); + } else if (ares == DW_DLV_OK) { + switch (attr) { + case DW_AT_name: + sres = dwarf_formstring(atlist[i], &temps, &err); + if (sres == DW_DLV_ERROR) { + print_error(dbg, + "formstring in get_proc_name failed", + sres, err); + /* 50 is safe wrong length since is bigger than the + actual string */ + safe_strcpy(proc_name_buf, proc_name_buf_len, + "ERROR in dwarf_formstring!", 50); + } else if (sres == DW_DLV_NO_ENTRY) { + /* 50 is safe wrong length since is bigger than the + actual string */ + safe_strcpy(proc_name_buf, proc_name_buf_len, + "NO ENTRY on dwarf_formstring?!", 50); + } else { + long len = (long) strlen(temps); + + safe_strcpy(proc_name_buf, proc_name_buf_len, temps, + len); + } + funcnamefound = 1; /* FOUND THE NAME */ + break; + case DW_AT_low_pc: + dres = dwarf_formaddr(atlist[i], &low_pc_die, &err); + if (dres == DW_DLV_ERROR) { + print_error(dbg, "formaddr in get_proc_name failed", + dres, err); + low_pc_die = ~low_pc; + /* ensure no match */ + } + funcpcfound = 1; + + break; + default: + break; + } + } + } + for (i = 0; i < atcnt; i++) { + dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR); + } + dwarf_dealloc(dbg, atlist, DW_DLA_LIST); + if (funcnamefound == 0 || funcpcfound == 0 || low_pc != low_pc_die) { + funcres = 0; + } + return (funcres); +} + +/* + Modified Depth First Search looking for the procedure: + a) only looks for children of subprogram. + b) With subprogram looks at current die *before* looking + for a child. + + Needed since some languages, including MP Fortran, + have nested functions. + Return 0 on failure, 1 on success. +*/ +static int +get_nested_proc_name(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc, + char *ret_name_buf, int ret_name_buf_len) +{ + char name_buf[BUFSIZ]; + Dwarf_Die curdie = die; + int die_locally_gotten = 0; + Dwarf_Die prev_child = 0; + Dwarf_Die newchild = 0; + Dwarf_Die newsibling = 0; + Dwarf_Half tag; + Dwarf_Error err = 0; + int chres = DW_DLV_OK; + + ret_name_buf[0] = 0; + while (chres == DW_DLV_OK) { + int tres; + + tres = dwarf_tag(curdie, &tag, &err); + newchild = 0; + err = 0; + if (tres == DW_DLV_OK) { + int lchres; + + if (tag == DW_TAG_subprogram) { + int proc_name_v; + + proc_name_v = get_proc_name(dbg, curdie, low_pc, + name_buf, BUFSIZ); + if (proc_name_v) { + /* this is it */ + safe_strcpy(ret_name_buf, ret_name_buf_len, + name_buf, (long) strlen(name_buf)); + if (die_locally_gotten) { + /* If we got this die from the parent, we do + not want to dealloc here! */ + dwarf_dealloc(dbg, curdie, DW_DLA_DIE); + } + return 1; + } + /* check children of subprograms recursively should + this really be check children of anything? */ + + lchres = dwarf_child(curdie, &newchild, &err); + if (lchres == DW_DLV_OK) { + /* look for inner subprogram */ + int newprog = + get_nested_proc_name(dbg, newchild, low_pc, + name_buf, BUFSIZ); + + dwarf_dealloc(dbg, newchild, DW_DLA_DIE); + if (newprog) { + /* Found it. We could just take this name or + we could concatenate names together For now, + just take name */ + if (die_locally_gotten) { + /* If we got this die from the parent, we + do not want to dealloc here! */ + dwarf_dealloc(dbg, curdie, DW_DLA_DIE); + } + safe_strcpy(ret_name_buf, ret_name_buf_len, + name_buf, (long) strlen(name_buf)); + return 1; + } + } else if (lchres == DW_DLV_NO_ENTRY) { + /* nothing to do */ + } else { + print_error(dbg, + "get_nested_proc_name dwarf_child() failed ", + chres, err); + if (die_locally_gotten) { + /* If we got this die from the parent, we do + not want to dealloc here! */ + dwarf_dealloc(dbg, curdie, DW_DLA_DIE); + } + return 0; + } + } /* end if TAG_subprogram */ + } else { + print_error(dbg, "no tag on child read ", tres, err); + if (die_locally_gotten) { + /* If we got this die from the parent, we do not want + to dealloc here! */ + dwarf_dealloc(dbg, curdie, DW_DLA_DIE); + } + return 0; + } + /* try next sibling */ + prev_child = curdie; + chres = dwarf_siblingof(dbg, curdie, &newsibling, &err); + if (chres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_cu_header On Child read ", chres, + err); + if (die_locally_gotten) { + /* If we got this die from the parent, we do not want + to dealloc here! */ + dwarf_dealloc(dbg, curdie, DW_DLA_DIE); + } + return 0; + } else if (chres == DW_DLV_NO_ENTRY) { + if (die_locally_gotten) { + /* If we got this die from the parent, we do not want + to dealloc here! */ + dwarf_dealloc(dbg, prev_child, DW_DLA_DIE); + } + return 0; /* proc name not at this level */ + } else { /* DW_DLV_OK */ + curdie = newsibling; + if (die_locally_gotten) { + /* If we got this die from the parent, we do not want + to dealloc here! */ + dwarf_dealloc(dbg, prev_child, DW_DLA_DIE); + } + prev_child = 0; + die_locally_gotten = 1; + } + + } + if (die_locally_gotten) { + /* If we got this die from the parent, we do not want to + dealloc here! */ + dwarf_dealloc(dbg, curdie, DW_DLA_DIE); + } + return 0; +} + +/* + For MP Fortran and possibly other languages, functions + nest! As a result, we must dig thru all functions, + not just the top level. + + + This remembers the CU die and restarts each search at the start + of the current cu. + + +*/ +string +get_fde_proc_name(Dwarf_Debug dbg, Dwarf_Addr low_pc) +{ + static char proc_name[BUFSIZ]; + Dwarf_Unsigned cu_header_length; + Dwarf_Unsigned abbrev_offset; + Dwarf_Half version_stamp; + Dwarf_Half address_size; + Dwarf_Unsigned next_cu_offset = 0; + int cures = DW_DLV_OK; + int dres = DW_DLV_OK; + int chres = DW_DLV_OK; + int looping = 0; + + if (current_cu_die_for_print_frames == NULL) { + cures + = dwarf_next_cu_header(dbg, &cu_header_length, + &version_stamp, &abbrev_offset, + &address_size, &next_cu_offset, + &err); + if (cures == DW_DLV_ERROR) { + return NULL; + } else if (cures == DW_DLV_NO_ENTRY) { + /* loop thru the list again */ + current_cu_die_for_print_frames = 0; + ++looping; + } else { /* DW_DLV_OK */ + dres = dwarf_siblingof(dbg, NULL, + ¤t_cu_die_for_print_frames, + &err); + if (dres == DW_DLV_ERROR) { + return NULL; + } + } + } + if (dres == DW_DLV_OK) { + Dwarf_Die child = 0; + + if (current_cu_die_for_print_frames == 0) { + /* no information. Possibly a stripped file */ + return NULL; + } + chres = + dwarf_child(current_cu_die_for_print_frames, &child, &err); + if (chres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_cu_header on child read ", chres, + err); + } else if (chres == DW_DLV_NO_ENTRY) { + } else { /* DW_DLV_OK */ + int gotname = + get_nested_proc_name(dbg, child, low_pc, proc_name, + BUFSIZ); + + dwarf_dealloc(dbg, child, DW_DLA_DIE); + if (gotname) { + return (proc_name); + } + child = 0; + } + } + for (;;) { + Dwarf_Die ldie; + + cures = dwarf_next_cu_header(dbg, &cu_header_length, + &version_stamp, &abbrev_offset, + &address_size, &next_cu_offset, + &err); + + if (cures != DW_DLV_OK) { + break; + } + + + dres = dwarf_siblingof(dbg, NULL, &ldie, &err); + + if (current_cu_die_for_print_frames) { + dwarf_dealloc(dbg, current_cu_die_for_print_frames, + DW_DLA_DIE); + } + current_cu_die_for_print_frames = 0; + if (dres == DW_DLV_ERROR) { + print_error(dbg, + "dwarf_cu_header Child Read finding proc name for .debug_frame", + chres, err); + continue; + } else if (dres == DW_DLV_NO_ENTRY) { + ++looping; + if (looping > 1) { + print_error(dbg, "looping on cu headers!", dres, err); + return NULL; + } + continue; + } + /* DW_DLV_OK */ + current_cu_die_for_print_frames = ldie; + { + int chres; + Dwarf_Die child; + + chres = + dwarf_child(current_cu_die_for_print_frames, &child, + &err); + if (chres == DW_DLV_ERROR) { + print_error(dbg, "dwarf Child Read ", chres, err); + } else if (chres == DW_DLV_NO_ENTRY) { + + ; /* do nothing, loop on cu */ + } else { /* DW_DLV_OK) */ + + int gotname = + get_nested_proc_name(dbg, child, low_pc, proc_name, + BUFSIZ); + + dwarf_dealloc(dbg, child, DW_DLA_DIE); + if (gotname) { + return (proc_name); + } + } + } + } + return (NULL); +} + +/* get all the data in .debug_frame (or .eh_frame). + The '3' versions mean print using the dwarf3 new interfaces. + The non-3 mean use the old interfaces. + All combinations of requests are possible. +*/ +extern void +print_frames(Dwarf_Debug dbg, int print_debug_frame, int print_eh_frame, + struct dwconf_s *config_data) +{ + Dwarf_Cie *cie_data = NULL; + Dwarf_Signed cie_element_count = 0; + Dwarf_Fde *fde_data = NULL; + Dwarf_Signed fde_element_count = 0; + Dwarf_Signed i; + int fres = 0; + Dwarf_Half address_size = 0; + int framed = 0; + + fres = dwarf_get_address_size(dbg, &address_size, &err); + if (fres != DW_DLV_OK) { + print_error(dbg, "dwarf_get_address_size", fres, err); + } + for (framed = 0; framed < 2; ++framed) { + char *framename = 0; + int silent_if_missing = 0; + int is_eh = 0; + + if (framed == 0) { + if (!print_debug_frame) { + continue; + } + framename = ".debug_frame"; + /* + * Big question here is how to print all the info? + * Can print the logical matrix, but that is huge, + * though could skip lines that don't change. + * Either that, or print the instruction statement program + * that describes the changes. + */ + fres = + dwarf_get_fde_list(dbg, &cie_data, &cie_element_count, + &fde_data, &fde_element_count, &err); + } else { + if (!print_eh_frame) { + continue; + } + is_eh = 1; + /* This is gnu g++ exceptions in a .eh_frame section. Which + is just like .debug_frame except that the empty, or + 'special' CIE_id is 0, not -1 (to distinguish fde from + cie). And the augmentation is "eh". As of egcs-1.1.2 + anyway. A non-zero cie_id is in a fde and is the + difference between the fde address and the beginning of + the cie it belongs to. This makes sense as this is + intended to be referenced at run time, and is part of + the running image. For more on augmentation strings, see + libdwarf/dwarf_frame.c. */ + + /* + * Big question here is how to print all the info? + * Can print the logical matrix, but that is huge, + * though could skip lines that don't change. + * Either that, or print the instruction statement program + * that describes the changes. + */ + silent_if_missing = 1; + framename = ".eh_frame"; + fres = + dwarf_get_fde_list_eh(dbg, &cie_data, + &cie_element_count, &fde_data, + &fde_element_count, &err); + } + if (fres == DW_DLV_ERROR) { + printf("\n%s\n", framename); + print_error(dbg, "dwarf_get_fde_list", fres, err); + } else if (fres == DW_DLV_NO_ENTRY) { + if (!silent_if_missing) + printf("\n%s\n", framename); + /* no frame information */ + } else { /* DW_DLV_OK */ + + printf("\n%s\n", framename); + printf("\nfde:\n"); + + for (i = 0; i < fde_element_count; i++) { + print_one_fde(dbg, fde_data[i], + i, cie_data, cie_element_count, + address_size, is_eh, config_data); + } + /* + Print the cie set. */ + if (verbose) { + printf("\ncie:\n"); + for (i = 0; i < cie_element_count; i++) { + print_one_cie(dbg, cie_data[i], i, address_size, + config_data); + } + } + dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_element_count, + fde_data, fde_element_count); + } + } + if (current_cu_die_for_print_frames) { + dwarf_dealloc(dbg, current_cu_die_for_print_frames, DW_DLA_DIE); + current_cu_die_for_print_frames = 0; + } +} + + + + +int + dwarf_get_section_max_offsets(Dwarf_Debug /* dbg */ , + Dwarf_Unsigned * /* debug_info_size + */ , + Dwarf_Unsigned * /* debug_abbrev_size + */ + , Dwarf_Unsigned * /* debug_line_size + */ , + Dwarf_Unsigned * /* debug_loc_size + */ , + Dwarf_Unsigned * + /* debug_aranges_size */ , + Dwarf_Unsigned * + /* debug_macinfo_size */ , + Dwarf_Unsigned * + /* debug_pubnames_size */ , + Dwarf_Unsigned * /* debug_str_size + */ , + Dwarf_Unsigned * /* debug_frame_size + */ + , Dwarf_Unsigned * /* debug_ranges_size + */ + , Dwarf_Unsigned * + /* debug_pubtypes_size */ ); + +/* The new (April 2005) dwarf_get_section_max_offsets() + in libdwarf returns all max-offsets, but we only + want one of those offsets. This function returns + the one we want from that set, + making functions needing this offset as readable as possible. + (avoiding code duplication). +*/ +static Dwarf_Unsigned +get_info_max_offset(Dwarf_Debug dbg) +{ + Dwarf_Unsigned debug_info_size = 0; + Dwarf_Unsigned debug_abbrev_size = 0; + Dwarf_Unsigned debug_line_size = 0; + Dwarf_Unsigned debug_loc_size = 0; + Dwarf_Unsigned debug_aranges_size = 0; + Dwarf_Unsigned debug_macinfo_size = 0; + Dwarf_Unsigned debug_pubnames_size = 0; + Dwarf_Unsigned debug_str_size = 0; + Dwarf_Unsigned debug_frame_size = 0; + Dwarf_Unsigned debug_ranges_size = 0; + Dwarf_Unsigned debug_pubtypes_size = 0; + + dwarf_get_section_max_offsets(dbg, + &debug_info_size, + &debug_abbrev_size, + &debug_line_size, + &debug_loc_size, + &debug_aranges_size, + &debug_macinfo_size, + &debug_pubnames_size, + &debug_str_size, + &debug_frame_size, + &debug_ranges_size, + &debug_pubtypes_size); + + return debug_info_size; +} + +/* This unifies the code for some error checks to + avoid code duplication. +*/ +static void +check_info_offset_sanity(char *sec, + char *field, + char *global, + Dwarf_Unsigned offset, Dwarf_Unsigned maxoff) +{ + if (maxoff == 0) { + /* Lets make a heuristic check. */ + if (offset > 0xffffffff) { + printf("Warning: section %s %s %s offset 0x%llx " + "exceptionally large \n", + sec, field, global, (unsigned long long) offset); + } + } + if (offset >= maxoff) { + printf("Warning: section %s %s %s offset 0x%llx " + "larger than max of 0x%llx\n", + sec, field, global, (unsigned long long) offset, + (unsigned long long) maxoff); + } +} + +/* Unified pubnames style output. + The error checking here against maxoff may be useless + (in that libdwarf may return an error if the offset is bad + and we will not get called here). + But we leave it in nonetheless as it looks sensible. + In at least one gigantic executable such offsets turned out wrong. +*/ +static void +print_pubname_style_entry(Dwarf_Debug dbg, + char *line_title, + char *name, + Dwarf_Unsigned die_off, + Dwarf_Unsigned cu_off, + Dwarf_Unsigned global_cu_offset, + Dwarf_Unsigned maxoff) +{ + Dwarf_Die die = NULL; + Dwarf_Die cu_die = NULL; + Dwarf_Off die_CU_off = 0; + int dres = 0; + int ddres = 0; + int cudres = 0; + + /* get die at die_off */ + dres = dwarf_offdie(dbg, die_off, &die, &err); + if (dres != DW_DLV_OK) + print_error(dbg, "dwarf_offdie", dres, err); + + /* get offset of die from its cu-header */ + ddres = dwarf_die_CU_offset(die, &die_CU_off, &err); + if (ddres != DW_DLV_OK) { + print_error(dbg, "dwarf_die_CU_offset", ddres, err); + } + + /* get die at offset cu_off */ + cudres = dwarf_offdie(dbg, cu_off, &cu_die, &err); + if (cudres != DW_DLV_OK) { + dwarf_dealloc(dbg, die, DW_DLA_DIE); + print_error(dbg, "dwarf_offdie", cudres, err); + } + printf("%s %-15s die-in-sect %lld, cu-in-sect %lld," + " die-in-cu %lld, cu-header-in-sect %lld", + line_title, name, (long long) die_off, (long long) cu_off, + /* the cu die offset */ + (long long) die_CU_off, + /* following is absolute offset of the ** beginning of the + cu */ + (long long) (die_off - die_CU_off)); + + if ((die_off - die_CU_off) != global_cu_offset) { + printf(" error: real cuhdr %llu", global_cu_offset); + exit(1); + } + if (verbose) { + printf(" cuhdr %llu", global_cu_offset); + } + + + dwarf_dealloc(dbg, die, DW_DLA_DIE); + dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); + + + printf("\n"); + + check_info_offset_sanity(line_title, + "die offset", name, die_off, maxoff); + check_info_offset_sanity(line_title, + "die cu offset", name, die_CU_off, maxoff); + check_info_offset_sanity(line_title, + "cu offset", name, + (die_off - die_CU_off), maxoff); + +} + + +/* get all the data in .debug_pubnames */ +extern void +print_pubnames(Dwarf_Debug dbg) +{ + Dwarf_Global *globbuf = NULL; + Dwarf_Signed count = 0; + Dwarf_Signed i = 0; + Dwarf_Off die_off = 0; + Dwarf_Off cu_off = 0; + char *name = 0; + int res = 0; + + printf("\n.debug_pubnames\n"); + res = dwarf_get_globals(dbg, &globbuf, &count, &err); + if (res == DW_DLV_ERROR) { + print_error(dbg, "dwarf_get_globals", res, err); + } else if (res == DW_DLV_NO_ENTRY) { + /* (err == 0 && count == DW_DLV_NOCOUNT) means there are no + pubnames. */ + } else { + Dwarf_Unsigned maxoff = get_info_max_offset(dbg); + + for (i = 0; i < count; i++) { + int nres; + int cures3; + Dwarf_Off global_cu_off = 0; + + nres = dwarf_global_name_offsets(globbuf[i], + &name, &die_off, &cu_off, + &err); + deal_with_name_offset_err(dbg, "dwarf_global_name_offsets", + name, die_off, nres, err); + + cures3 = dwarf_global_cu_offset(globbuf[i], + &global_cu_off, &err); + if (cures3 != DW_DLV_OK) { + print_error(dbg, "dwarf_global_cu_offset", cures3, err); + } + + print_pubname_style_entry(dbg, + "global", + name, die_off, cu_off, + global_cu_off, maxoff); + + /* print associated die too? */ + + if (check_pubname_attr) { + Dwarf_Bool has_attr; + int ares; + int dres; + Dwarf_Die die; + + /* get die at die_off */ + dres = dwarf_offdie(dbg, die_off, &die, &err); + if (dres != DW_DLV_OK) { + print_error(dbg, "dwarf_offdie", dres, err); + } + + + ares = + dwarf_hasattr(die, DW_AT_external, &has_attr, &err); + if (ares == DW_DLV_ERROR) { + print_error(dbg, "hassattr on DW_AT_external", ares, + err); + } + pubname_attr_result.checks++; + if (ares == DW_DLV_OK && has_attr) { + /* Should the value of flag be examined? */ + } else { + pubname_attr_result.errors++; + DWARF_CHECK_ERROR2(name, + "pubname does not have DW_AT_external") + } + dwarf_dealloc(dbg, die, DW_DLA_DIE); + } + } + dwarf_globals_dealloc(dbg, globbuf, count); + } +} /* print_pubnames() */ + + +struct macro_counts_s { + long mc_start_file; + long mc_end_file; + long mc_define; + long mc_undef; + long mc_extension; + long mc_code_zero; + long mc_unknown; +}; + +static void +print_one_macro_entry_detail(long i, + char *type, + struct Dwarf_Macro_Details_s *mdp) +{ + /* "DW_MACINFO_*: section-offset file-index [line] string\n" */ + if (mdp->dmd_macro) { + printf("%3ld %s: %6llu %2lld [%4lld] \"%s\" \n", + i, + type, + mdp->dmd_offset, + mdp->dmd_fileindex, mdp->dmd_lineno, mdp->dmd_macro); + } else { + printf("%3ld %s: %6llu %2lld [%4lld] 0\n", + i, + type, + mdp->dmd_offset, mdp->dmd_fileindex, mdp->dmd_lineno); + } + +} + +static void +print_one_macro_entry(long i, + struct Dwarf_Macro_Details_s *mdp, + struct macro_counts_s *counts) +{ + + switch (mdp->dmd_type) { + case 0: + counts->mc_code_zero++; + print_one_macro_entry_detail(i, "DW_MACINFO_type-code-0", mdp); + break; + + case DW_MACINFO_start_file: + counts->mc_start_file++; + print_one_macro_entry_detail(i, "DW_MACINFO_start_file", mdp); + break; + + case DW_MACINFO_end_file: + counts->mc_end_file++; + print_one_macro_entry_detail(i, "DW_MACINFO_end_file ", mdp); + break; + + case DW_MACINFO_vendor_ext: + counts->mc_extension++; + print_one_macro_entry_detail(i, "DW_MACINFO_vendor_ext", mdp); + break; + + case DW_MACINFO_define: + counts->mc_define++; + print_one_macro_entry_detail(i, "DW_MACINFO_define ", mdp); + break; + + case DW_MACINFO_undef: + counts->mc_undef++; + print_one_macro_entry_detail(i, "DW_MACINFO_undef ", mdp); + break; + + default: + { + char create_type[50]; /* More than large enough. */ + + counts->mc_unknown++; + snprintf(create_type, sizeof(create_type), + "DW_MACINFO_0x%x", mdp->dmd_type); + print_one_macro_entry_detail(i, create_type, mdp); + } + break; + } +} + +/* print data in .debug_macinfo */ +/* FIXME: should print name of file whose index is in macro data + here -- somewhere. +*/ + /*ARGSUSED*/ extern void +print_macinfo(Dwarf_Debug dbg) +{ + Dwarf_Off offset = 0; + Dwarf_Unsigned max = 0; + Dwarf_Signed count = 0; + long group = 0; + Dwarf_Macro_Details *maclist = NULL; + int lres = 0; + + printf("\n.debug_macinfo\n"); + + while ((lres = dwarf_get_macro_details(dbg, offset, + max, &count, &maclist, + &err)) == DW_DLV_OK) { + long i; + struct macro_counts_s counts; + + + memset(&counts, 0, sizeof(counts)); + + printf("\n"); + printf("compilation-unit .debug_macinfo # %ld\n", group); + printf + ("num name section-offset file-index [line] \"string\"\n"); + for (i = 0; i < count; i++) { + struct Dwarf_Macro_Details_s *mdp = &maclist[i]; + + print_one_macro_entry(i, mdp, &counts); + } + + if (counts.mc_start_file == 0) { + printf + ("DW_MACINFO file count of zero is invalid DWARF2/3\n"); + } + if (counts.mc_start_file != counts.mc_end_file) { + printf("Counts of DW_MACINFO file (%ld) end_file (%ld) " + "do not match!.\n", + counts.mc_start_file, counts.mc_end_file); + } + if (counts.mc_code_zero < 1) { + printf("Count of zeros in macro group should be non-zero " + "(1 preferred), count is %ld\n", + counts.mc_code_zero); + } + printf("Macro counts: start file %ld, " + "end file %ld, " + "define %ld, " + "undef %ld " + "ext %ld, " + "code-zero %ld, " + "unknown %ld\n", + counts.mc_start_file, + counts.mc_end_file, + counts.mc_define, + counts.mc_undef, + counts.mc_extension, + counts.mc_code_zero, counts.mc_unknown); + + + /* int type= maclist[count - 1].dmd_type; */ + /* ASSERT: type is zero */ + + offset = maclist[count - 1].dmd_offset + 1; + dwarf_dealloc(dbg, maclist, DW_DLA_STRING); + ++group; + } + if (lres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_get_macro_details", lres, err); + } +} + +/* print data in .debug_loc */ +extern void +print_locs(Dwarf_Debug dbg) +{ + Dwarf_Unsigned offset = 0; + Dwarf_Addr hipc_offset = 0; + Dwarf_Addr lopc_offset = 0; + Dwarf_Ptr data = 0; + Dwarf_Unsigned entry_len = 0; + Dwarf_Unsigned next_entry = 0; + int lres = 0; + + printf("\n.debug_loc format means " + "section-offset begin-addr end-addr length-of-block-entry\n"); + while ((lres = dwarf_get_loclist_entry(dbg, offset, + &hipc_offset, &lopc_offset, + &data, &entry_len, + &next_entry, + &err)) == DW_DLV_OK) { + printf("\t 0x%08llx 0x%09llx " "0x%08llx " "%8lld\n", + (long long) offset, (long long) lopc_offset, + (long long) hipc_offset, (long long) entry_len); + offset = next_entry; + } + if (lres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_get_loclist_entry", lres, err); + } +} + +/* print data in .debug_abbrev */ +extern void +print_abbrevs(Dwarf_Debug dbg) +{ + Dwarf_Abbrev ab; + Dwarf_Unsigned offset = 0; + Dwarf_Unsigned length = 0; + Dwarf_Unsigned attr_count = 0; + Dwarf_Half tag = 0; + Dwarf_Half attr = 0; + Dwarf_Signed form = 0; + Dwarf_Off off = 0; + Dwarf_Unsigned i = 0; + string child_name; + Dwarf_Unsigned abbrev_num = 1; + Dwarf_Signed child_flag = 0; + int abres = 0; + int tres = 0; + int acres = 0; + Dwarf_Unsigned abbrev_code = 0; + + printf("\n.debug_abbrev\n"); + while ((abres = dwarf_get_abbrev(dbg, offset, &ab, + &length, &attr_count, + &err)) == DW_DLV_OK) { + + if (attr_count == 0) { + /* Simple innocuous zero : null abbrev entry */ + if (dense) { + printf("<%lld><%lld><%lld><%s>\n", abbrev_num, offset, (signed long long) /* abbrev_code + */ 0, + "null .debug_abbrev entry"); + } else { + printf("<%4lld><%5lld> %-20s\n", abbrev_num, offset, (signed long long) /* abbrev_code + */ 0, + "null .debug_abbrev entry"); + } + + offset += length; + ++abbrev_num; + dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); + continue; + } + tres = dwarf_get_abbrev_tag(ab, &tag, &err); + if (tres != DW_DLV_OK) { + dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); + print_error(dbg, "dwarf_get_abbrev_tag", tres, err); + } + tres = dwarf_get_abbrev_code(ab, &abbrev_code, &err); + if (tres != DW_DLV_OK) { + dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); + print_error(dbg, "dwarf_get_abbrev_code", tres, err); + } + if (dense) + printf("<%lld><%lld><%lld><%s>", abbrev_num, + offset, abbrev_code, get_TAG_name(dbg, tag)); + else + printf("<%4lld><%5lld> %-20s", abbrev_num, + offset, abbrev_code, get_TAG_name(dbg, tag)); + ++abbrev_num; + acres = dwarf_get_abbrev_children_flag(ab, &child_flag, &err); + if (acres == DW_DLV_ERROR) { + dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); + print_error(dbg, "dwarf_get_abbrev_children_flag", acres, + err); + } + if (acres == DW_DLV_NO_ENTRY) { + child_flag = 0; + } + child_name = get_children_name(dbg, child_flag); + if (dense) + printf(" %s", child_name); + else + printf("%s\n", child_name); + /* Abbrev just contains the format of a die, which debug_info + then points to with the real data. So here we just print the + given format. */ + for (i = 0; i < attr_count; i++) { + int aeres; + + aeres = + dwarf_get_abbrev_entry(ab, i, &attr, &form, &off, &err); + if (aeres == DW_DLV_ERROR) { + dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); + print_error(dbg, "dwarf_get_abbrev_entry", aeres, err); + } + if (aeres == DW_DLV_NO_ENTRY) { + attr = -1LL; + form = -1LL; + } + if (dense) + printf(" <%ld>%s<%s>", (unsigned long) off, + get_AT_name(dbg, attr), + get_FORM_name(dbg, (Dwarf_Half) form)); + else + printf(" <%5ld>\t%-28s%s\n", + (unsigned long) off, get_AT_name(dbg, attr), + get_FORM_name(dbg, (Dwarf_Half) form)); + } + dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); + offset += length; + if (dense) + printf("\n"); + } + if (abres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_get_abbrev", abres, err); + } +} + +/* print data in .debug_string */ +extern void +print_strings(Dwarf_Debug dbg) +{ + Dwarf_Signed length = 0; + string name; + Dwarf_Off offset = 0; + int sres = 0; + + printf("\n.debug_string\n"); + while ((sres = dwarf_get_str(dbg, offset, &name, &length, &err)) + == DW_DLV_OK) { + printf("name at offset %lld, length %lld is %s\n", + offset, length, name); + offset += length + 1; + } + /* An inability to find the section is not necessarily + a real error, so do not report error unless we've + seen a real record. */ + if(sres == DW_DLV_ERROR && offset != 0) { + print_error(dbg, "dwarf_get_str failure", sres, err); + } +} + +/* get all the data in .debug_aranges */ +extern void +print_aranges(Dwarf_Debug dbg) +{ + Dwarf_Signed count = 0; + Dwarf_Signed i = 0; + Dwarf_Arange *arange_buf = NULL; + Dwarf_Addr start = 0; + Dwarf_Unsigned length = 0; + Dwarf_Off cu_die_offset = 0; + Dwarf_Die cu_die = NULL; + int ares = 0; + int aires = 0; + + printf("\n.debug_aranges\n"); + ares = dwarf_get_aranges(dbg, &arange_buf, &count, &err); + if (ares == DW_DLV_ERROR) { + print_error(dbg, "dwarf_get_aranges", ares, err); + } else if (ares == DW_DLV_NO_ENTRY) { + /* no arange is included */ + } else { + for (i = 0; i < count; i++) { + aires = dwarf_get_arange_info(arange_buf[i], + &start, &length, + &cu_die_offset, &err); + if (aires != DW_DLV_OK) { + print_error(dbg, "dwarf_get_arange_info", aires, err); + } else { + int dres; + + dres = dwarf_offdie(dbg, cu_die_offset, &cu_die, &err); + if (dres != DW_DLV_OK) { + print_error(dbg, "dwarf_offdie", dres, err); + } else { + if (cu_name_flag) { + Dwarf_Half tag; + Dwarf_Attribute attrib; + Dwarf_Half theform; + int tres; + int dares; + int fres; + + tres = dwarf_tag(cu_die, &tag, &err); + if (tres != DW_DLV_OK) { + print_error(dbg, "dwarf_tag in aranges", + tres, err); + } + dares = + dwarf_attr(cu_die, DW_AT_name, &attrib, + &err); + if (dares != DW_DLV_OK) { + print_error(dbg, "dwarf_attr arange" + " derived die has no name", + dres, err); + } + fres = dwarf_whatform(attrib, &theform, &err); + if (fres == DW_DLV_OK) { + if (theform == DW_FORM_string + || theform == DW_FORM_strp) { + string temps; + int sres; + + sres = + dwarf_formstring(attrib, &temps, + &err); + if (sres == DW_DLV_OK) { + string p = temps; + + if (cu_name[0] != '/') { + p = strrchr(temps, '/'); + if (p == NULL) { + p = temps; + } else { + p++; + } + } + if (!strcmp(cu_name, p)) { + } else { + continue; + } + } else { + print_error(dbg, + "arange: string missing", + sres, err); + } + } + } else { + print_error(dbg, + "dwarf_whatform unexpected value", + fres, err); + } + dwarf_dealloc(dbg, attrib, DW_DLA_ATTR); + } + printf("\narange starts at %llx, " + "length of %lld, cu_die_offset = %lld", + start, length, cu_die_offset); + /* get the offset of the cu header itself in the + section */ + { + Dwarf_Off off = 0; + int cures3 = + dwarf_get_arange_cu_header_offset(arange_buf + [i], + &off, + &err); + + if (cures3 != DW_DLV_OK) { + print_error(dbg, "dwarf_get_cu_hdr_offset", + cures3, err); + } + if (verbose) + printf(" cuhdr %llu", off); + } + printf("\n"); + print_one_die(dbg, cu_die, (boolean) TRUE, + /* srcfiles= */ 0, + /* cnt= */ 0); + + dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); + } + } + /* print associated die too? */ + dwarf_dealloc(dbg, arange_buf[i], DW_DLA_ARANGE); + } + dwarf_dealloc(dbg, arange_buf, DW_DLA_LIST); + } +} + +/* Get all the data in .debug_static_funcs + On error, this allows some dwarf memory leaks. +*/ +extern void +print_static_funcs(Dwarf_Debug dbg) +{ + Dwarf_Func *funcbuf = NULL; + Dwarf_Signed count = 0; + Dwarf_Signed i = 0; + Dwarf_Off die_off = 0; + Dwarf_Off cu_off = 0; + int gfres = 0; + + printf("\n.debug_static_func\n"); + gfres = dwarf_get_funcs(dbg, &funcbuf, &count, &err); + if (gfres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_get_funcs", gfres, err); + } else if (gfres == DW_DLV_NO_ENTRY) { + /* no static funcs */ + } else { + Dwarf_Unsigned maxoff = get_info_max_offset(dbg); + + for (i = 0; i < count; i++) { + int fnres; + int cures3; + Dwarf_Unsigned global_cu_off = 0; + char *name = 0; + + fnres = + dwarf_func_name_offsets(funcbuf[i], &name, &die_off, + &cu_off, &err); + deal_with_name_offset_err(dbg, "dwarf_func_name_offsets", + name, die_off, fnres, err); + + cures3 = dwarf_func_cu_offset(funcbuf[i], + &global_cu_off, &err); + if (cures3 != DW_DLV_OK) { + print_error(dbg, "dwarf_global_cu_offset", cures3, err); + } + + print_pubname_style_entry(dbg, + "static-func", name, die_off, + cu_off, global_cu_off, maxoff); + + + /* print associated die too? */ + if (check_pubname_attr) { + Dwarf_Bool has_attr; + int ares; + int dres; + Dwarf_Die die; + + /* get die at die_off */ + dres = dwarf_offdie(dbg, die_off, &die, &err); + if (dres != DW_DLV_OK) { + print_error(dbg, "dwarf_offdie", dres, err); + } + + + ares = + dwarf_hasattr(die, DW_AT_external, &has_attr, &err); + if (ares == DW_DLV_ERROR) { + print_error(dbg, "hassattr on DW_AT_external", ares, + err); + } + pubname_attr_result.checks++; + if (ares == DW_DLV_OK && has_attr) { + /* Should the value of flag be examined? */ + } else { + pubname_attr_result.errors++; + DWARF_CHECK_ERROR2(name, + "pubname does not have DW_AT_external") + } + dwarf_dealloc(dbg, die, DW_DLA_DIE); + } + } + dwarf_funcs_dealloc(dbg, funcbuf, count); + } +} /* print_static_funcs() */ + +/* get all the data in .debug_static_vars */ +extern void +print_static_vars(Dwarf_Debug dbg) +{ + Dwarf_Var *varbuf = NULL; + Dwarf_Signed count = 0; + Dwarf_Signed i = 0; + Dwarf_Off die_off = 0; + Dwarf_Off cu_off = 0; + char *name = 0; + int gvres = 0; + + printf("\n.debug_static_vars\n"); + gvres = dwarf_get_vars(dbg, &varbuf, &count, &err); + if (gvres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_get_vars", gvres, err); + } else if (gvres == DW_DLV_NO_ENTRY) { + /* no static vars */ + } else { + Dwarf_Unsigned maxoff = get_info_max_offset(dbg); + + for (i = 0; i < count; i++) { + int vnres; + int cures3; + Dwarf_Off global_cu_off = 0; + + vnres = + dwarf_var_name_offsets(varbuf[i], &name, &die_off, + &cu_off, &err); + deal_with_name_offset_err(dbg, + "dwarf_var_name_offsets", + name, die_off, vnres, err); + + cures3 = dwarf_var_cu_offset(varbuf[i], + &global_cu_off, &err); + if (cures3 != DW_DLV_OK) { + print_error(dbg, "dwarf_global_cu_offset", cures3, err); + } + + print_pubname_style_entry(dbg, + "static-var", + name, die_off, cu_off, + global_cu_off, maxoff); + + /* print associated die too? */ + } + dwarf_vars_dealloc(dbg, varbuf, count); + } +} /* print_static_vars */ + +/* get all the data in .debug_types */ +extern void +print_types(Dwarf_Debug dbg, enum type_type_e type_type) +{ + Dwarf_Type *typebuf = NULL; + Dwarf_Signed count = 0; + Dwarf_Signed i = 0; + Dwarf_Off die_off = 0; + Dwarf_Off cu_off = 0; + char *name = NULL; + int gtres = 0; + + char *section_name = NULL; + char *offset_err_name = NULL; + char *section_open_name = NULL; + char *print_name_prefix = NULL; + int (*get_types) (Dwarf_Debug, Dwarf_Type **, Dwarf_Signed *, + Dwarf_Error *) + = 0; + int (*get_offset) (Dwarf_Type, char **, Dwarf_Off *, Dwarf_Off *, + Dwarf_Error *) = NULL; + int (*get_cu_offset) (Dwarf_Type, Dwarf_Off *, Dwarf_Error *) = + NULL; + void (*dealloctype) (Dwarf_Debug, Dwarf_Type *, Dwarf_Signed) = + NULL; + + + if (type_type == DWARF_PUBTYPES) { + section_name = ".debug_pubtypes"; + offset_err_name = "dwarf_pubtype_name_offsets"; + section_open_name = "dwarf_get_pubtypes"; + print_name_prefix = "pubtype"; + get_types = dwarf_get_pubtypes; + get_offset = dwarf_pubtype_name_offsets; + get_cu_offset = dwarf_pubtype_cu_offset; + dealloctype = dwarf_pubtypes_dealloc; + } else { + /* SGI_TYPENAME */ + section_name = ".debug_typenames"; + offset_err_name = "dwarf_type_name_offsets"; + section_open_name = "dwarf_get_types"; + print_name_prefix = "type"; + get_types = dwarf_get_types; + get_offset = dwarf_type_name_offsets; + get_cu_offset = dwarf_type_cu_offset; + dealloctype = dwarf_types_dealloc; + } + + + + gtres = get_types(dbg, &typebuf, &count, &err); + if (gtres == DW_DLV_ERROR) { + print_error(dbg, section_open_name, gtres, err); + } else if (gtres == DW_DLV_NO_ENTRY) { + /* no types */ + } else { + Dwarf_Unsigned maxoff = get_info_max_offset(dbg); + + /* Before July 2005, the section name was printed + unconditionally, now only prints if non-empty section really + exists. */ + printf("\n%s\n", section_name); + + for (i = 0; i < count; i++) { + int tnres; + int cures3; + Dwarf_Off global_cu_off = 0; + + tnres = + get_offset(typebuf[i], &name, &die_off, &cu_off, &err); + deal_with_name_offset_err(dbg, offset_err_name, name, + die_off, tnres, err); + + cures3 = get_cu_offset(typebuf[i], &global_cu_off, &err); + + if (cures3 != DW_DLV_OK) { + print_error(dbg, "dwarf_var_cu_offset", cures3, err); + } + print_pubname_style_entry(dbg, + print_name_prefix, + name, die_off, cu_off, + global_cu_off, maxoff); + + /* print associated die too? */ + } + dealloctype(dbg, typebuf, count); + } +} /* print_types() */ + +/* get all the data in .debug_weaknames */ +extern void +print_weaknames(Dwarf_Debug dbg) +{ + Dwarf_Weak *weaknamebuf = NULL; + Dwarf_Signed count = 0; + Dwarf_Signed i = 0; + Dwarf_Off die_off = 0; + Dwarf_Off cu_off = 0; + char *name = NULL; + int wkres = 0; + + printf("\n.debug_weaknames\n"); + wkres = dwarf_get_weaks(dbg, &weaknamebuf, &count, &err); + if (wkres == DW_DLV_ERROR) { + print_error(dbg, "dwarf_get_weaks", wkres, err); + } else if (wkres == DW_DLV_NO_ENTRY) { + /* no weaknames */ + } else { + Dwarf_Unsigned maxoff = get_info_max_offset(dbg); + + for (i = 0; i < count; i++) { + int tnres; + int cures3; + + Dwarf_Unsigned global_cu_off = 0; + + tnres = dwarf_weak_name_offsets(weaknamebuf[i], + &name, &die_off, &cu_off, + &err); + deal_with_name_offset_err(dbg, + "dwarf_weak_name_offsets", + name, die_off, tnres, err); + + cures3 = dwarf_weak_cu_offset(weaknamebuf[i], + &global_cu_off, &err); + + if (cures3 != DW_DLV_OK) { + print_error(dbg, "dwarf_weakname_cu_offset", + cures3, err); + } + print_pubname_style_entry(dbg, + "weakname", + name, die_off, cu_off, + global_cu_off, maxoff); + + /* print associated die too? */ + } + dwarf_weaks_dealloc(dbg, weaknamebuf, count); + } +} /* print_weaknames() */ + + + +/* + decode ULEB +*/ +Dwarf_Unsigned +local_dwarf_decode_u_leb128(unsigned char *leb128, + unsigned int *leb128_length) +{ + unsigned char byte = 0; + Dwarf_Unsigned number = 0; + unsigned int shift = 0; + unsigned int byte_length = 1; + + byte = *leb128; + for (;;) { + number |= (byte & 0x7f) << shift; + shift += 7; + + if ((byte & 0x80) == 0) { + if (leb128_length != NULL) + *leb128_length = byte_length; + return (number); + } + + byte_length++; + byte = *(++leb128); + } +} + +#define BITSINBYTE 8 +Dwarf_Signed +local_dwarf_decode_s_leb128(unsigned char *leb128, + unsigned int *leb128_length) +{ + Dwarf_Signed number = 0; + Dwarf_Bool sign = 0; + Dwarf_Signed shift = 0; + unsigned char byte = *leb128; + Dwarf_Signed byte_length = 1; + + /* byte_length being the number of bytes of data absorbed so far in + turning the leb into a Dwarf_Signed. */ + + for (;;) { + sign = byte & 0x40; + number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift; + shift += 7; + + if ((byte & 0x80) == 0) { + break; + } + ++leb128; + byte = *leb128; + byte_length++; + } + + if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) { + number |= -((Dwarf_Signed) 1 << shift); + } + + if (leb128_length != NULL) + *leb128_length = byte_length; + return (number); +} + + +/* Dumping a dwarf-expression as a byte stream. */ +void +dump_block(char *prefix, char *data, Dwarf_Signed len) +{ + char *end_data = data + len; + char *cur = data; + int i = 0; + + printf("%s", prefix); + for (; cur < end_data; ++cur, ++i) { + if (i > 0 && i % 4 == 0) + printf(" "); + printf("%02x", 0xff & *cur); + + } +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/tag_attr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/tag_attr.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,288 @@ +/* + Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + + +$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_attr.c,v 1.8 2005/12/01 17:34:59 davea Exp $ */ +#include +#include +#include /* For exit() declaration etc. */ +#include /* For errno declaration. */ + + +/* The following is the magic token used to + distinguish real tags/attrs from group-delimiters. + Blank lines have been eliminated by an awk script. +*/ +#define MAGIC_TOKEN_VALUE 0xffffffff + +/* Expected input format + +0xffffffff +value of a tag +value of a standard attribute that follows that tag +... +0xffffffff +value of a tag +value of a standard attribute that follows that tag +... +0xffffffff +... + +No blank lines or commentary allowed, no symbols, just numbers. + + +*/ + + +/* We don't need really long lines: the input file is simple. */ +#define MAX_LINE_SIZE 1000 + +/* 1 more than the higest number in the DW_TAG defines. */ +#define TABLE_SIZE 0x41 + +/* Enough entries to have a bit for each standard legal attr. */ +#define COLUMN_COUNT 4 + +/* Bits per 'int' to mark legal attrs. */ +#define BITS_PER_WORD 32 + +static unsigned int + tag_attr_combination_table[TABLE_SIZE][COLUMN_COUNT]; +static char *tag_name[] = { + "0x00", + "0x01 DW_TAG_array_type", + "0x02 DW_TAG_class_type", + "0x03 DW_TAG_entry_point", + "0x04 DW_TAG_enumeration_type", + "0x05 DW_TAG_formal_parameter", + "0x06", + "0x07", + "0x08 DW_TAG_imported_declaration", + "0x09", + "0x0a DW_TAG_label", + "0x0b DW_TAG_lexical_block", + "0x0c", + "0x0d DW_TAG_member", + "0x0e", + "0x0f DW_TAG_pointer_type", + "0x10 DW_TAG_reference_type", + "0x11 DW_TAG_compile_unit", + "0x12 DW_TAG_string_type", + "0x13 DW_TAG_structure_type", + "0x14", + "0x15 DW_TAG_subroutine_type", + "0x16 DW_TAG_typedef", + "0x17 DW_TAG_union_type", + "0x18 DW_TAG_unspecified_parameters", + "0x19 DW_TAG_variant", + "0x1a DW_TAG_common_block", + "0x1b DW_TAG_common_inclusion", + "0x1c DW_TAG_inheritance", + "0x1d DW_TAG_inlined_subroutine", + "0x1e DW_TAG_module", + "0x1f DW_TAG_ptr_to_member_type", + "0x20 DW_TAG_set_type", + "0x21 DW_TAG_subrange_type", + "0x22 DW_TAG_with_stmt", + "0x23 DW_TAG_access_declaration", + "0x24 DW_TAG_base_type", + "0x25 DW_TAG_catch_block", + "0x26 DW_TAG_const_type", + "0x27 DW_TAG_constant", + "0x28 DW_TAG_enumerator", + "0x29 DW_TAG_file_type", + "0x2a DW_TAG_friend", + "0x2b DW_TAG_namelist", + "0x2c DW_TAG_namelist_item", + "0x2d DW_TAG_packed_type", + "0x2e DW_TAG_subprogram", + "0x2f DW_TAG_template_type_parameter", + "0x30 DW_TAG_template_value_parameter", + "0x31 DW_TAG_thrown_type", + "0x32 DW_TAG_try_block", + "0x33 DW_TAG_variant_part", + "0x34 DW_TAG_variable", + "0x35 DW_TAG_volatile_type", + "0x36 DW_TAG_dwarf_procedure", + "0x37 DW_TAG_restrict_type", + "0x38 DW_TAG_interface_type", + "0x39 DW_TAG_namespace", + "0x3a DW_TAG_imported_module", + "0x3b DW_TAG_unspecified_type", + "0x3c DW_TAG_partial_unit", + "0x3d DW_TAG_imported_unit", + "0x3e", /* was DW_TAG_mutable_type, removed + from DWARF3f. */ + "0x3f DW_TAG_condition", + "0x40 DW_TAG_shared_type", +}; + +static int linecount = 0; +static char line_in[MAX_LINE_SIZE]; + +#define IS_EOF 1 +#define NOT_EOF 0 + +#define MAX_LINE_SIZE 1000 + + +static void +bad_line_input(char *msg) +{ + fprintf(stderr, + "tag_attr table build failed %s, line %d: \"%s\" \n", + msg, linecount, line_in); + exit(1); + +} +static void +trim_newline(char *line, int max) +{ + char *end = line + max - 1; + + for (; *line && (line < end); ++line) { + if (*line == '\n') { + /* Found newline, drop it */ + *line = 0; + return; + } + } + + return; +} + + +/* Reads a value from the text table. + Exits with non-zero status + if the table is erroneous in some way. +*/ +static int +read_value(unsigned int *outval) +{ + char *res = 0; + FILE *file = stdin; + unsigned long lval; + char *strout = 0; + + ++linecount; + *outval = 0; + res = fgets(line_in, sizeof(line_in), file); + if (res == 0) { + if (ferror(file)) { + fprintf(stderr, + "tag_attr: Error reading table, %d lines read\n", + linecount); + exit(1); + } + if (feof(file)) { + return IS_EOF; + } + /* impossible */ + fprintf(stderr, "tag_attr: Impossible error reading table, " + "%d lines read\n", linecount); + exit(1); + } + trim_newline(line_in, sizeof(line_in)); + errno = 0; + lval = strtoul(line_in, &strout, 0); + if (strout == line_in) { + bad_line_input("bad number input!"); + } + if (errno != 0) { + int myerr = errno; + + fprintf(stderr, "tag_attr errno %d\n", myerr); + bad_line_input("invalid number on line"); + } + *outval = (int) lval; + return NOT_EOF; +} + +int +main() +{ + int i; + unsigned int num; + int input_eof; + + + input_eof = read_value(&num); /* 0xffffffff */ + if (IS_EOF == input_eof) { + bad_line_input("Empty input file"); + } + if (num != MAGIC_TOKEN_VALUE) { + bad_line_input("Expected 0xffffffff"); + } + while (!feof(stdin)) { + unsigned int tag; + + input_eof = read_value(&tag); + if (IS_EOF == input_eof) { + /* Reached normal eof */ + break; + } + if (tag >= TABLE_SIZE) { + bad_line_input("tag value exceeds table size"); + } + input_eof = read_value(&num); + if (IS_EOF == input_eof) { + bad_line_input("Not terminated correctly.."); + } + while (num != MAGIC_TOKEN_VALUE) { + unsigned idx = num / BITS_PER_WORD; + unsigned bit = num % BITS_PER_WORD; + + if (idx >= COLUMN_COUNT) { + bad_line_input + ("too many attributes: table incomplete."); + } + tag_attr_combination_table[tag][idx] |= (1 << bit); + input_eof = read_value(&num); + if (IS_EOF == input_eof) { + bad_line_input("Not terminated correctly."); + } + } + } + printf("static unsigned int tag_attr_combination_table [ ][%d]" + " = {\n", COLUMN_COUNT); + for (i = 0; i < TABLE_SIZE; i++) { + printf("/* %-37s*/\n", tag_name[i]); + printf(" { %#.8x, %#.8x, %#.8x, %#.8x,},\n", + tag_attr_combination_table[i][0], + tag_attr_combination_table[i][1], + tag_attr_combination_table[i][2], + tag_attr_combination_table[i][3] + ); + } + printf("};\n"); + return (0); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/tag_attr.list --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/tag_attr.list Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,812 @@ +/* + Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + +$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_attr.list,v 1.7 2005/12/01 17:34:59 davea Exp $ +*/ +#include + +/* + list for semantic check of tag-attr relation. + + 0xffffffff is a "punctuation." The final line of this file + must be 0xffffffff. The next line after each 0xffffffff + (except the final line) is a tag. The lines after this line + before the next 0xffffffff are the attributes that can be given + to the tag." + + For example, + + 0xffffffff + DW_TAG_access_declaration + DW_AT_decl_column + DW_AT_decl_file + DW_AT_decl_line + DW_AT_accessibility + DW_AT_name + DW_AT_sibling + 0xffffffff + + means "only DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line, + DW_AT_accessibility, DW_AT_name and DW_AT_sibling can be given to + DW_TAG_access_declaration." + + This file is applied to the preprocessor, thus any C comment and + preprocessor control line is available. + */ + +0xffffffff +DW_TAG_access_declaration +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_accessibility +DW_AT_name +DW_AT_sibling +0xffffffff +DW_TAG_array_type +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_accessibility +DW_AT_allocated +DW_AT_associated +DW_AT_bit_stride +DW_AT_byte_size +DW_AT_data_location +DW_AT_declaration +DW_AT_description +DW_AT_name +DW_AT_ordering +DW_AT_sibling +DW_AT_specification +DW_AT_start_scope +DW_AT_type +DW_AT_visibility +0xffffffff +DW_TAG_base_type +DW_AT_allocated +DW_AT_associated +DW_AT_binary_scale +DW_AT_bit_offset +DW_AT_bit_size +DW_AT_byte_size +DW_AT_data_location +DW_AT_decimal_scale +DW_AT_decimal_sign +DW_AT_description +DW_AT_digit_count +DW_AT_encoding +DW_AT_endianity +DW_AT_name +DW_AT_name +DW_AT_picture_string +DW_AT_sibling +DW_AT_small +0xffffffff +DW_TAG_catch_block +DW_AT_abstract_origin +DW_AT_high_pc +DW_AT_low_pc +DW_AT_ranges +DW_AT_segment +DW_AT_sibling +0xffffffff +DW_TAG_class_type +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_accessibility +DW_AT_allocated +DW_AT_associated +DW_AT_byte_size +DW_AT_data_location +DW_AT_declaration +DW_AT_description +DW_AT_name +DW_AT_sibling +DW_AT_specification +DW_AT_start_scope +DW_AT_visibility +0xffffffff +DW_TAG_common_block +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_declaration +DW_AT_location +DW_AT_name +DW_AT_segment +DW_AT_sibling +DW_AT_visibility +0xffffffff +DW_TAG_common_inclusion +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_common_reference +DW_AT_declaration +DW_AT_sibling +DW_AT_visibility +0xffffffff +DW_TAG_compile_unit +DW_AT_base_types +DW_AT_comp_dir +DW_AT_identifier_case +DW_AT_high_pc +DW_AT_language +DW_AT_low_pc +DW_AT_macro_info +DW_AT_name +DW_AT_producer +DW_AT_ranges +DW_AT_segment +DW_AT_sibling +DW_AT_stmt_list +DW_AT_use_UTF8 +0xffffffff +DW_TAG_condition +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_name +DW_AT_sibling +0xffffffff +DW_TAG_const_type +DW_AT_allocated +DW_AT_associated +DW_AT_data_location +DW_AT_name +DW_AT_sibling +DW_AT_type +0xffffffff +DW_TAG_constant +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_accessibility +DW_AT_const_value +DW_AT_declaration +DW_AT_description +DW_AT_endianity +DW_AT_external +DW_AT_name +DW_AT_sibling +DW_AT_start_scope +DW_AT_type +DW_AT_visibility +0xffffffff +DW_TAG_dwarf_procedure +DW_AT_location +0xffffffff +DW_TAG_entry_point +DW_AT_address_class +DW_AT_description +DW_AT_low_pc +DW_AT_name +DW_AT_return_addr +DW_AT_segment +DW_AT_sibling +DW_AT_static_link +DW_AT_type +0xffffffff +DW_TAG_enumeration_type +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_accessibility +DW_AT_allocated +DW_AT_associated +DW_AT_bit_stride +DW_AT_byte_size +DW_AT_byte_stride +DW_AT_data_location +DW_AT_declaration +DW_AT_description +DW_AT_name +DW_AT_sibling +DW_AT_specification +DW_AT_start_scope +DW_AT_type +DW_AT_visibility +0xffffffff +DW_TAG_enumerator +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_const_value +DW_AT_description +DW_AT_name +DW_AT_sibling +0xffffffff +DW_TAG_file_type +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_allocated +DW_AT_associated +DW_AT_byte_size +DW_AT_data_location +DW_AT_description +DW_AT_name +DW_AT_sibling +DW_AT_start_scope +DW_AT_type +DW_AT_visibility +0xffffffff +DW_TAG_formal_parameter +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_artificial +DW_AT_const_value +DW_AT_default_value +DW_AT_description +DW_AT_endianity +DW_AT_is_optional +DW_AT_location +DW_AT_name +DW_AT_segment +DW_AT_sibling +DW_AT_type +DW_AT_variable_parameter +0xffffffff +DW_TAG_friend +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_friend +DW_AT_sibling +0xffffffff +DW_TAG_imported_declaration +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_accessibility +DW_AT_description +DW_AT_import +DW_AT_name +DW_AT_sibling +DW_AT_start_scope +0xffffffff +DW_TAG_imported_module +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_import +DW_AT_sibling +DW_AT_start_scope +0xffffffff +DW_TAG_imported_unit +DW_AT_import +0xffffffff +DW_TAG_inheritance +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_accessibility +DW_AT_data_member_location +DW_AT_sibling +DW_AT_type +DW_AT_virtuality +0xffffffff +DW_TAG_inlined_subroutine +DW_AT_abstract_origin +DW_AT_call_column +DW_AT_call_file +DW_AT_call_line +DW_AT_entry_pc +DW_AT_high_pc +DW_AT_low_pc +DW_AT_ranges +DW_AT_return_addr +DW_AT_segment +DW_AT_sibling +DW_AT_start_scope +DW_AT_trampoline +0xffffffff +DW_TAG_interface_type +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_accessibility +DW_AT_description +DW_AT_name +DW_AT_sibling +DW_AT_start_scope +0xffffffff +DW_TAG_label +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_description +DW_AT_low_pc +DW_AT_name +DW_AT_segment +DW_AT_start_scope +DW_AT_sibling +0xffffffff +DW_TAG_lexical_block +DW_AT_abstract_origin +DW_AT_description +DW_AT_high_pc +DW_AT_low_pc +DW_AT_name +DW_AT_ranges +DW_AT_segment +DW_AT_sibling +0xffffffff +DW_TAG_member +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_accessibility +DW_AT_bit_offset +DW_AT_bit_size +DW_AT_byte_size +DW_AT_data_member_location +DW_AT_declaration +DW_AT_description +DW_AT_mutable +DW_AT_name +DW_AT_sibling +DW_AT_type +DW_AT_visibility +0xffffffff +DW_TAG_module +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_accessibility +DW_AT_declaration +DW_AT_description +DW_AT_entry_pc +DW_AT_high_pc +DW_AT_low_pc +DW_AT_name +DW_AT_priority +DW_AT_segment +DW_AT_sibling +DW_AT_specification +DW_AT_visibility +0xffffffff +DW_TAG_namelist +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_accessibility +DW_AT_abstract_origin +DW_AT_declaration +DW_AT_name +DW_AT_sibling +DW_AT_visibility +0xffffffff +DW_TAG_namelist_item +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_namelist_item +DW_AT_sibling +0xffffffff +DW_TAG_namespace +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_description +DW_AT_extension +DW_AT_name +DW_AT_sibling +DW_AT_start_scope +0xffffffff +DW_TAG_packed_type +DW_AT_allocated +DW_AT_associated +DW_AT_data_location +DW_AT_name +DW_AT_sibling +DW_AT_type +0xffffffff +DW_TAG_partial_unit +DW_AT_base_types +DW_AT_comp_dir +DW_AT_description +DW_AT_identifier_case +DW_AT_high_pc +DW_AT_language +DW_AT_low_pc +DW_AT_macro_info +DW_AT_name +DW_AT_producer +DW_AT_ranges +DW_AT_segment +DW_AT_sibling +DW_AT_stmt_list +DW_AT_use_UTF8 +0xffffffff +DW_TAG_pointer_type +DW_AT_address_class +DW_AT_allocated +DW_AT_associated +DW_AT_data_location +DW_AT_name +DW_AT_sibling +DW_AT_specification +DW_AT_type +/* Comment from 1993: + "Though DWARF spec doesn't refer to DW_AT_byte_size, it may well be + given to DW_TAG_pointer_type." + Comment 29 Nov 2005 by David Anderrson + DW_AT_byte_size would be legal, but what would it mean, given + not specifically defined by the DWARF spec? + Byte size of the pointer or the pointed-to item? + Both should already be known for the ABI/instruction-set + in use. + Cannot recall why, but SGI/IRIX/MIPS uses this. + */ +DW_AT_byte_size +0xffffffff +DW_TAG_ptr_to_member_type +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_address_class +DW_AT_allocated +DW_AT_associated +DW_AT_containing_type +DW_AT_data_location +DW_AT_declaration +DW_AT_description +DW_AT_name +DW_AT_sibling +DW_AT_type +DW_AT_use_location +DW_AT_visibility +0xffffffff +DW_TAG_reference_type +DW_AT_address_class +DW_AT_allocated +DW_AT_associated +DW_AT_data_location +DW_AT_name +DW_AT_sibling +DW_AT_type +0xffffffff +DW_TAG_restrict_type +DW_AT_allocated +DW_AT_associated +DW_AT_data_location +DW_AT_name +DW_AT_sibling +DW_AT_type +0xffffffff +DW_TAG_set_type +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_accessibility +DW_AT_allocated +DW_AT_associated +DW_AT_byte_size +DW_AT_data_location +DW_AT_declaration +DW_AT_description +DW_AT_name +DW_AT_start_scope +DW_AT_sibling +DW_AT_type +DW_AT_visibility +0xffffffff +DW_TAG_shared_type +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_count +DW_AT_name +DW_AT_sibling +DW_AT_type +0xffffffff +DW_TAG_string_type +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_accessibility +DW_AT_allocated +DW_AT_associated +DW_AT_byte_size +DW_AT_data_location +DW_AT_declaration +DW_AT_description +DW_AT_name +DW_AT_segment +DW_AT_sibling +DW_AT_start_scope +DW_AT_string_length +DW_AT_visibility +0xffffffff +DW_TAG_structure_type +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_accessibility +DW_AT_allocated +DW_AT_associated +DW_AT_byte_size +DW_AT_data_location +DW_AT_declaration +DW_AT_description +DW_AT_name +DW_AT_sibling +DW_AT_specification +DW_AT_start_scope +DW_AT_visibility +0xffffffff +DW_TAG_subprogram +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_accessibility +DW_AT_address_class +DW_AT_artificial +DW_AT_calling_convention +DW_AT_declaration +DW_AT_description +DW_AT_elemental +DW_AT_entry_pc +DW_AT_explicit +DW_AT_external +DW_AT_frame_base +DW_AT_high_pc +DW_AT_inline +DW_AT_low_pc +DW_AT_name +DW_AT_object_pointer +DW_AT_prototyped +DW_AT_pure +DW_AT_ranges +DW_AT_recursive +DW_AT_return_addr +DW_AT_segment +DW_AT_sibling +DW_AT_specification +DW_AT_start_scope +DW_AT_static_link +DW_AT_trampoline +DW_AT_type +DW_AT_visibility +DW_AT_virtuality +DW_AT_vtable_elem_location +0xffffffff +DW_TAG_subrange_type +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_accessibility +DW_AT_allocated +DW_AT_associated +DW_AT_bit_stride +DW_AT_byte_size +DW_AT_byte_stride +DW_AT_count +DW_AT_data_location +DW_AT_declaration +DW_AT_description +DW_AT_lower_bound +DW_AT_name +DW_AT_sibling +DW_AT_threads_scaled +DW_AT_type +DW_AT_upper_bound +DW_AT_visibility +0xffffffff +DW_TAG_subroutine_type +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_accessibility +DW_AT_address_class +DW_AT_allocated +DW_AT_associated +DW_AT_data_location +DW_AT_declaration +DW_AT_description +DW_AT_name +DW_AT_prototyped +DW_AT_sibling +DW_AT_start_scope +DW_AT_type +DW_AT_visibility +0xffffffff +DW_TAG_template_type_parameter +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_description +DW_AT_name +DW_AT_sibling +DW_AT_type +0xffffffff +DW_TAG_template_value_parameter +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_const_value +DW_AT_description +DW_AT_name +DW_AT_sibling +DW_AT_type +0xffffffff +DW_TAG_thrown_type +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_allocated +DW_AT_associated +DW_AT_data_location +DW_AT_sibling +DW_AT_type +0xffffffff +DW_TAG_try_block +DW_AT_abstract_origin +DW_AT_high_pc +DW_AT_low_pc +DW_AT_ranges +DW_AT_segment +DW_AT_sibling +0xffffffff +DW_TAG_typedef +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_accessibility +DW_AT_allocated +DW_AT_associated +DW_AT_data_location +DW_AT_declaration +DW_AT_description +DW_AT_name +DW_AT_sibling +DW_AT_start_scope +DW_AT_type +DW_AT_visibility +0xffffffff +DW_TAG_union_type +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_accessibility +DW_AT_allocated +DW_AT_associated +DW_AT_byte_size +DW_AT_data_location +DW_AT_declaration +DW_AT_description +DW_AT_name +DW_AT_sibling +DW_AT_specification +DW_AT_start_scope +DW_AT_visibility +0xffffffff +DW_TAG_unspecified_parameters +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_artificial +DW_AT_sibling +0xffffffff +DW_TAG_unspecified_type +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_description +DW_AT_sibling +0xffffffff +DW_TAG_variable +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_abstract_origin +DW_AT_accessibility +DW_AT_byte_size +DW_AT_const_value +DW_AT_declaration +DW_AT_description +DW_AT_endianity +DW_AT_external +DW_AT_location +DW_AT_name +DW_AT_segment +DW_AT_sibling +DW_AT_specification +DW_AT_start_scope +DW_AT_type +DW_AT_visibility +0xffffffff +DW_TAG_variant +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_accessibility +DW_AT_abstract_origin +DW_AT_declaration +DW_AT_discr_list +DW_AT_discr_value +DW_AT_sibling +0xffffffff +DW_TAG_variant_part +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_accessibility +DW_AT_abstract_origin +DW_AT_declaration +DW_AT_discr +DW_AT_sibling +DW_AT_type +0xffffffff +DW_TAG_volatile_type +DW_AT_allocated +DW_AT_associated +DW_AT_data_location +DW_AT_name +DW_AT_sibling +DW_AT_type +0xffffffff +DW_TAG_with_stmt +DW_AT_accessibility +DW_AT_address_class +DW_AT_declaration +DW_AT_high_pc +DW_AT_location +DW_AT_low_pc +DW_AT_ranges +DW_AT_segment +DW_AT_sibling +DW_AT_type +DW_AT_visibility +0xffffffff diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/tag_tree.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/tag_tree.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,293 @@ +/* + Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + + +$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_tree.c,v 1.8 2005/12/01 17:34:59 davea Exp $ */ +#include +#include +#include /* For exit() declaration etc. */ +#include /* For errno declaration. */ + + +/* The following is the magic token used to + distinguish real tags/attrs from group-delimiters. + Blank lines have been eliminated by an awk script. +*/ +#define MAGIC_TOKEN_VALUE 0xffffffff + +/* Expected input format + +0xffffffff +value of a tag +value of a standard tag that may be a child ofthat tag +... +0xffffffff +value of a tag +value of a standard tag that may be a child ofthat tag +... +0xffffffff +... + +No blank lines or commentary allowed, no symbols, just numbers. + + +*/ + + +/* We don't need really long lines: the input file is simple. */ +#define MAX_LINE_SIZE 1000 + +/* 1 more than the higest number in the DW_TAG defines. */ +#define TABLE_SIZE 0x41 + +/* Enough entries to have a bit for each standard legal tag. */ +#define COLUMN_COUNT 2 + +/* Bits per 'int' to mark legal attrs. */ +#define BITS_PER_WORD 32 + + + +#define TABLE_SIZE 0x41 + +static unsigned int + tag_tree_combination_table[TABLE_SIZE][COLUMN_COUNT]; +static char *tag_name[] = { + "0x00", + "0x01 DW_TAG_array_type", + "0x02 DW_TAG_class_type", + "0x03 DW_TAG_entry_point", + "0x04 DW_TAG_enumeration_type", + "0x05 DW_TAG_formal_parameter", + "0x06", + "0x07", + "0x08 DW_TAG_imported_declaration", + "0x09", + "0x0a DW_TAG_label", + "0x0b DW_TAG_lexical_block", + "0x0c", + "0x0d DW_TAG_member", + "0x0e", + "0x0f DW_TAG_pointer_type", + "0x10 DW_TAG_reference_type", + "0x11 DW_TAG_compile_unit", + "0x12 DW_TAG_string_type", + "0x13 DW_TAG_structure_type", + "0x14", + "0x15 DW_TAG_subroutine_type", + "0x16 DW_TAG_typedef", + "0x17 DW_TAG_union_type", + "0x18 DW_TAG_unspecified_parameters", + "0x19 DW_TAG_variant", + "0x1a DW_TAG_common_block", + "0x1b DW_TAG_common_inclusion", + "0x1c DW_TAG_inheritance", + "0x1d DW_TAG_inlined_subroutine", + "0x1e DW_TAG_module", + "0x1f DW_TAG_ptr_to_member_type", + "0x20 DW_TAG_set_type", + "0x21 DW_TAG_subrange_type", + "0x22 DW_TAG_with_stmt", + "0x23 DW_TAG_access_declaration", + "0x24 DW_TAG_base_type", + "0x25 DW_TAG_catch_block", + "0x26 DW_TAG_const_type", + "0x27 DW_TAG_constant", + "0x28 DW_TAG_enumerator", + "0x29 DW_TAG_file_type", + "0x2a DW_TAG_friend", + "0x2b DW_TAG_namelist", + "0x2c DW_TAG_namelist_item", + "0x2d DW_TAG_packed_type", + "0x2e DW_TAG_subprogram", + "0x2f DW_TAG_template_type_parameter", + "0x30 DW_TAG_template_value_parameter", + "0x31 DW_TAG_thrown_type", + "0x32 DW_TAG_try_block", + "0x33 DW_TAG_variant_part", + "0x34 DW_TAG_variable", + "0x35 DW_TAG_volatile_type", + "0x36 DW_TAG_dwarf_procedure", + "0x37 DW_TAG_restrict_type", + "0x38 DW_TAG_interface_type", + "0x39 DW_TAG_namespace", + "0x3a DW_TAG_imported_module", + "0x3b DW_TAG_unspecified_type", + "0x3c DW_TAG_partial_unit", + "0x3d DW_TAG_imported_unit", + "0x3e", /* was DW_TAG_mutable_type, removed + from DWARF3f. */ + "0x3f DW_TAG_condition", + "0x40 DW_TAG_shared_type", +}; + +static int linecount = 0; +static char line_in[MAX_LINE_SIZE]; + +#define IS_EOF 1 +#define NOT_EOF 0 + +#define MAX_LINE_SIZE 1000 + + +static void +bad_line_input(char *msg) +{ + fprintf(stderr, + "tag_tree table build failed %s, line %d: \"%s\" \n", + msg, linecount, line_in); + exit(1); + +} +static void +trim_newline(char *line, int max) +{ + char *end = line + max - 1; + + for (; *line && (line < end); ++line) { + if (*line == '\n') { + /* Found newline, drop it */ + *line = 0; + return; + } + } + + return; +} + + +/* Reads a value from the text table. + Exits with non-zero status + if the table is erroneous in some way. +*/ +static int +read_value(unsigned int *outval) +{ + char *res = 0; + FILE *file = stdin; + unsigned long lval; + char *strout = 0; + + ++linecount; + *outval = 0; + res = fgets(line_in, sizeof(line_in), file); + if (res == 0) { + if (ferror(file)) { + fprintf(stderr, + "tag_attr: Error reading table, %d lines read\n", + linecount); + exit(1); + } + if (feof(file)) { + return IS_EOF; + } + /* impossible */ + fprintf(stderr, "tag_attr: Impossible error reading table, " + "%d lines read\n", linecount); + exit(1); + } + trim_newline(line_in, sizeof(line_in)); + errno = 0; + lval = strtoul(line_in, &strout, 0); + if (strout == line_in) { + bad_line_input("bad number input!"); + } + if (errno != 0) { + int myerr = errno; + + fprintf(stderr, "tag_attr errno %d\n", myerr); + bad_line_input("invalid number on line"); + } + *outval = (int) lval; + return NOT_EOF; +} + + +int +main() +{ + int i; + unsigned int num; + int input_eof; + + + input_eof = read_value(&num); /* 0xffffffff */ + if (IS_EOF == input_eof) { + bad_line_input("Empty input file"); + } + if (num != MAGIC_TOKEN_VALUE) { + bad_line_input("Expected 0xffffffff"); + } + + while (!feof(stdin)) { + unsigned int tag; + + input_eof = read_value(&tag); + if (IS_EOF == input_eof) { + /* Reached normal eof */ + break; + } + if (tag >= TABLE_SIZE) { + bad_line_input("tag value exceeds table size"); + } + input_eof = read_value(&num); + if (IS_EOF == input_eof) { + bad_line_input("Not terminated correctly.."); + } + + while (num != 0xffffffff) { + int idx = num / BITS_PER_WORD; + int bit = num % BITS_PER_WORD; + + if (idx >= COLUMN_COUNT) { + bad_line_input("too many TAGs: table incomplete."); + } + + tag_tree_combination_table[tag][idx] |= (1 << bit); + input_eof = read_value(&num); + if (IS_EOF == input_eof) { + bad_line_input("Not terminated correctly."); + } + } + } + printf + ("static unsigned int tag_tree_combination_table [ ][%d] = {\n", + COLUMN_COUNT); + for (i = 0; i < TABLE_SIZE; i++) { + printf("/* %-37s*/\n", tag_name[i]); + printf(" { %#.8x, %#.8x},\n", + tag_tree_combination_table[i][0], + tag_tree_combination_table[i][1]); + } + printf("};\n"); + return (0); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/tag_tree.list --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/tag_tree.list Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,403 @@ +/* + Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + +$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_tree.list,v 1.6 2005/12/01 17:34:59 davea Exp $ +*/ +#include + +/* + list for semantic check of tag-tree. + + 0xffffffff is a "punctuation." The final line of this file + must be 0xffffffff. The next line after each 0xffffffff + (except the final line) stands for "parent-tag." The lines + after this line before the next 0xffffffff are the tags that + can be children of the "parent-tag." + + For example, + + 0xffffffff + DW_TAG_array_type + DW_TAG_subrange_type + DW_TAG_enumeration_type + 0xffffffff + + means "only DW_TAG_subrange_type and DW_TAG_enumeration_type can + be children of DW_TAG_array_type. + + This file is applied to the preprocessor, thus any C comment and + preprocessor control line is available. + */ + +0xffffffff +DW_TAG_access_declaration +0xffffffff +DW_TAG_array_type +DW_TAG_subrange_type +DW_TAG_enumeration_type +0xffffffff +DW_TAG_base_type +0xffffffff +DW_TAG_catch_block +DW_TAG_formal_parameter +DW_TAG_unspecified_parameters +DW_TAG_array_type +DW_TAG_class_type +DW_TAG_enumeration_type +DW_TAG_pointer_type +DW_TAG_reference_type +DW_TAG_string_type +DW_TAG_structure_type +DW_TAG_subroutine_type +DW_TAG_typedef +DW_TAG_union_type +DW_TAG_ptr_to_member_type +DW_TAG_set_type +DW_TAG_subrange_type +DW_TAG_base_type +DW_TAG_const_type +DW_TAG_constant +DW_TAG_file_type +DW_TAG_packed_type +DW_TAG_subprogram +DW_TAG_variable +DW_TAG_volatile_type +0xffffffff +DW_TAG_class_type +DW_TAG_member +DW_TAG_inheritance +DW_TAG_access_declaration +DW_TAG_friend +DW_TAG_ptr_to_member_type +DW_TAG_subprogram +DW_TAG_template_type_parameter /* template instantiations */ +DW_TAG_template_value_parameter /* template instantiations */ +DW_TAG_typedef +DW_TAG_base_type +DW_TAG_pointer_type +DW_TAG_union_type +DW_TAG_const_type +0xffffffff +DW_TAG_common_block +DW_TAG_variable +0xffffffff +DW_TAG_common_inclusion +0xffffffff +DW_TAG_compile_unit +DW_TAG_array_type +DW_TAG_class_type +DW_TAG_enumeration_type +DW_TAG_imported_declaration +DW_TAG_pointer_type +DW_TAG_reference_type +DW_TAG_string_type +DW_TAG_structure_type +DW_TAG_subroutine_type +DW_TAG_typedef +DW_TAG_union_type +DW_TAG_common_block +DW_TAG_inlined_subroutine +DW_TAG_module +DW_TAG_ptr_to_member_type +DW_TAG_set_type +DW_TAG_subrange_type +DW_TAG_base_type +DW_TAG_const_type +DW_TAG_constant +DW_TAG_file_type +DW_TAG_namelist +DW_TAG_namespace +DW_TAG_packed_type +DW_TAG_subprogram +DW_TAG_variable +DW_TAG_volatile_type +0xffffffff +DW_TAG_condition /* COBOL */ +DW_TAG_constant +DW_TAG_subrange_type +0xffffffff +DW_TAG_const_type +0xffffffff +DW_TAG_constant +0xffffffff +DW_TAG_dwarf_procedure +0xffffffff +DW_TAG_entry_point +DW_TAG_formal_parameter +DW_TAG_unspecified_parameters +DW_TAG_common_inclusion +0xffffffff +DW_TAG_enumeration_type +DW_TAG_enumerator +0xffffffff +DW_TAG_enumerator +0xffffffff +DW_TAG_file_type +0xffffffff +DW_TAG_formal_parameter +0xffffffff +DW_TAG_friend +0xffffffff +DW_TAG_imported_declaration +0xffffffff +DW_TAG_imported_module +0xffffffff +DW_TAG_imported_unit +0xffffffff +DW_TAG_inheritance +0xffffffff +DW_TAG_inlined_subroutine +DW_TAG_formal_parameter +DW_TAG_unspecified_parameters +DW_TAG_array_type +DW_TAG_class_type +DW_TAG_enumeration_type +DW_TAG_pointer_type +DW_TAG_reference_type +DW_TAG_string_type +DW_TAG_structure_type +DW_TAG_subroutine_type +DW_TAG_lexical_block +DW_TAG_typedef +DW_TAG_union_type +DW_TAG_inlined_subroutine +DW_TAG_ptr_to_member_type +DW_TAG_set_type +DW_TAG_subrange_type +DW_TAG_base_type +DW_TAG_const_type +DW_TAG_constant +DW_TAG_file_type +DW_TAG_namelist +DW_TAG_packed_type +DW_TAG_subprogram +DW_TAG_variable +DW_TAG_volatile_type +0xffffffff +DW_TAG_interface_type +DW_TAG_member +DW_TAG_subprogram +0xffffffff +DW_TAG_label +0xffffffff +DW_TAG_lexical_block +DW_TAG_array_type +DW_TAG_class_type +DW_TAG_enumeration_type +DW_TAG_imported_declaration +DW_TAG_pointer_type +DW_TAG_reference_type +DW_TAG_string_type +DW_TAG_structure_type +DW_TAG_subroutine_type +DW_TAG_typedef +DW_TAG_union_type +DW_TAG_inlined_subroutine +DW_TAG_lexical_block +DW_TAG_module +DW_TAG_ptr_to_member_type +DW_TAG_set_type +DW_TAG_subrange_type +DW_TAG_base_type +DW_TAG_const_type +DW_TAG_constant +DW_TAG_namelist +DW_TAG_packed_type +DW_TAG_subprogram +DW_TAG_variable +DW_TAG_volatile_type +0xffffffff +DW_TAG_member +0xffffffff +DW_TAG_module +0xffffffff +DW_TAG_namelist +DW_TAG_namelist_item +0xffffffff +DW_TAG_namelist_item +0xffffffff +DW_TAG_namespace +DW_TAG_array_type +DW_TAG_class_type +DW_TAG_enumeration_type +DW_TAG_imported_declaration +DW_TAG_pointer_type +DW_TAG_reference_type +DW_TAG_string_type +DW_TAG_structure_type +DW_TAG_subroutine_type +DW_TAG_typedef +DW_TAG_union_type +DW_TAG_common_block +DW_TAG_inlined_subroutine +DW_TAG_module +DW_TAG_ptr_to_member_type +DW_TAG_set_type +DW_TAG_subrange_type +DW_TAG_base_type +DW_TAG_const_type +DW_TAG_constant +DW_TAG_namelist +DW_TAG_packed_type +DW_TAG_subprogram +DW_TAG_variable +DW_TAG_volatile_type +0xffffffff +DW_TAG_packed_type +0xffffffff +DW_TAG_partial_unit +DW_TAG_array_type +DW_TAG_class_type +DW_TAG_enumeration_type +DW_TAG_imported_declaration +DW_TAG_pointer_type +DW_TAG_reference_type +DW_TAG_string_type +DW_TAG_structure_type +DW_TAG_subroutine_type +DW_TAG_typedef +DW_TAG_union_type +DW_TAG_common_block +DW_TAG_inlined_subroutine +DW_TAG_module +DW_TAG_ptr_to_member_type +DW_TAG_set_type +DW_TAG_subrange_type +DW_TAG_base_type +DW_TAG_const_type +DW_TAG_constant +DW_TAG_file_type +DW_TAG_namelist +DW_TAG_packed_type +DW_TAG_subprogram +DW_TAG_variable +DW_TAG_volatile_type +0xffffffff +DW_TAG_pointer_type +0xffffffff +DW_TAG_ptr_to_member_type +0xffffffff +DW_TAG_reference_type +0xffffffff +DW_TAG_restrict_type +0xffffffff +DW_TAG_set_type +0xffffffff +DW_TAG_shared_type +0xffffffff +DW_TAG_string_type +0xffffffff +DW_TAG_structure_type +DW_TAG_member +DW_TAG_inheritance +DW_TAG_access_declaration +DW_TAG_friend +DW_TAG_ptr_to_member_type +DW_TAG_variant_part +DW_TAG_subprogram +DW_TAG_template_type_parameter /* template instantiations */ +DW_TAG_template_value_parameter /* template instantiations */ +DW_TAG_typedef +DW_TAG_base_type +DW_TAG_pointer_type +DW_TAG_union_type +DW_TAG_const_type +0xffffffff +DW_TAG_subprogram +DW_TAG_formal_parameter +DW_TAG_unspecified_parameters +DW_TAG_thrown_type +DW_TAG_template_type_parameter +DW_TAG_common_inclusion +DW_TAG_common_block +DW_TAG_array_type +DW_TAG_class_type +DW_TAG_enumeration_type +DW_TAG_pointer_type +DW_TAG_reference_type +DW_TAG_string_type +DW_TAG_lexical_block +DW_TAG_structure_type +DW_TAG_subroutine_type +DW_TAG_typedef +DW_TAG_union_type +DW_TAG_inlined_subroutine +DW_TAG_ptr_to_member_type +DW_TAG_set_type +DW_TAG_subrange_type +DW_TAG_base_type +DW_TAG_const_type +DW_TAG_constant +DW_TAG_file_type +DW_TAG_namelist +DW_TAG_packed_type +DW_TAG_subprogram +DW_TAG_variable +DW_TAG_volatile_type +DW_TAG_label +0xffffffff +DW_TAG_subrange_type +0xffffffff +DW_TAG_subroutine_type +DW_TAG_formal_parameter +DW_TAG_unspecified_parameters +0xffffffff +DW_TAG_template_type_parameter +0xffffffff +DW_TAG_template_value_parameter +0xffffffff +DW_TAG_thrown_type +0xffffffff +DW_TAG_try_block +0xffffffff +DW_TAG_typedef +0xffffffff +DW_TAG_union_type +DW_TAG_member +DW_TAG_friend +0xffffffff +DW_TAG_unspecified_parameters +0xffffffff +DW_TAG_unspecified_type +0xffffffff +DW_TAG_variable +0xffffffff +DW_TAG_variant +DW_TAG_variant_part +0xffffffff +DW_TAG_variant_part +0xffffffff +DW_TAG_volatile_type +0xffffffff +DW_TAG_with_stmt +0xffffffff diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/dwarfdump/testesb.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/testesb.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,78 @@ +/* testesb.c + test code for esb.h esb.c + + Not part of a compiled dwarfdump. + +*/ + +#include +#include +typedef char *string; + +#include "esb.h" + +void +check(string msg, struct esb_s *data, string v) +{ + string b = esb_get_string(data); + size_t l = 0; + size_t alloc = 0; + + if (strcmp(b, v)) { + fprintf(stderr, "ERROR: %s content error %s != %s\n", msg, b, + v); + } + + l = esb_string_len(data); + + if (l != strlen(v)) { + fprintf(stderr, "ERROR: %s length error %lu != %lu\n", msg, + (unsigned long) l, (unsigned long) strlen(v)); + } + alloc = esb_get_allocated_size(data); + if (l > alloc) { + fprintf(stderr, "ERROR: %s allocation error %lu > %lu\n", msg, + (unsigned long) l, (unsigned long) alloc); + + } + + return; +} + +int +main(void) +{ + struct esb_s data; + + + esb_alloc_size(2); /* small to get all code paths tested. */ + esb_constructor(&data); + + esb_append(&data, "a"); + esb_appendn(&data, "bc", 1); + esb_append(&data, "d"); + esb_append(&data, "e"); + check("test 1", &data, "abde"); + + esb_destructor(&data); + esb_constructor(&data); + + esb_append(&data, "abcdefghij" "0123456789"); + check("test 2", &data, "abcdefghij" "0123456789"); + + esb_destructor(&data); + esb_constructor(&data); + esb_append(&data, "abcdefghij" "0123456789"); + + esb_append(&data, "abcdefghij" "0123456789"); + + esb_append(&data, "abcdefghij" "0123456789"); + + esb_append(&data, "abcdefghij" "0123456789"); + check("test 3", &data, "abcdefghij" + "0123456789" + "abcdefghij" + "0123456789" + "abcdefghij" "0123456789" "abcdefghij" "0123456789"); + return 0; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/CHANGES --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/CHANGES Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,102 @@ + + +------------------------------------------------------------- +April 14, 2000 davea@sgi.com +Corrected minor bugs in production of 32bit dwarf with +64 bit pointers. Fixed omissions in legal +DIE children of a DIE. Make small changes in +description of regster output in frame information +access. + +------------------------------------------------------------- +Mar 7, 2000 davea@sgi.com +Corrected line table reading so it will handle +reading an object with a diffent number of standard +op codes than at libdwarf compile time. +This was possible all along, but libdwarf did +not do it right. + +------------------------------------------------------------- +Dec 8, 1999 davea@sgi.com +Changed nearly all files. +Adding the capability to read and produce +the new, accepted by committee, but not +released-publically 64bit extension proposal +dwarf data. +This allows dwarf compilation units +with 64bit section offsets and 32bit +sections offsets to be mixed. +So that offsets can grow very large with +64-bit pointer applications (though 64bit pointers +and 64bit offsets are not the same notion). + +In addition, removed all the contents (or nearly all) +of the dwarf_funcs.c dwarf_weaks.c dwarf_vars.c, +and dwarf_types.c, as the data format is identical +to dwarf globals (pubnames) and there is no need +to duplicate all that code. + +All these sections whose contents were gutted are things that +are formatted exactly like pubnames, and all are sgi +extensions. Now the implementation uses pubnames code +(dwarf_global.c) to do the work for all the pubnames-like +sections. + +The (minor, IMO) difference is that in case of an incorrect +dwarf file (leading to libdwarf being unable to process +something in one of the sgi-specific pubnames-like sections) +the dwarf error string may reference pubnames when weaks, +static functions, static variables, or global typenames are +actually the problem. This is fixable, however the price would +appear to be that even globals would need to call a helper +function (to pass in the correct error return). Right now the +dwarf_weaks.c calls the dwarf_global.c function, for example, +with no extra arguments indicating the true section involved. +(Other approaches keeping the original error codes exist. +Producing the code uniquely via macros seems unappealing. +Inline functions would be ok though. This version does not +inline the functions we are talking about, such as +dwarf_global_name_offsets() when called from +dwarf_type_name_offsets().) + +Since these extra sections are SGI only and only really used by +SGI's workshop product, and the performance hit is small, the +extra function calls in reading each seem acceptable. + + +------------------------------------------------------------- +Sep 29,1999 davea@sgi.com +Changed many files, so that it is easy to switch +from 32bit-offset-only (like cygnus +and dwarf2 v 2.0.0) to sgi/mips 64 bit dwarf. +See NEWS for more info on 32bit-offset. + + +------------------------------------------------------------- +Since Oct 95 and before May, 1996 + +Added the function dwarf_get_cie_of_fde() which makes it possible +to remember a single fde/cie set out of a block usefully. + +Enhanced doc of dwarf_bitoffset() + +Added new function dwarf_global_formref() so all reference +forms can be retrieved. + +Fixed bug in retrieving array bounds: was failing to sign extend +formsdata. + +Added function dwarf_get_fde_info_for_all_regs(), which makes +retrieval of the complete set of registers (as needed by +debuggers and exception handlers) effectively N times faster +than getting them one a time where N is the number of registers. + +Added support for exception table handling (really just support +for a reference to an exception table for c++ exceptions). + +Fixed a bug where useless extra space (several megabytes) +were malloc'ed for the abbreviations table by the libdwarf +consumer code. + +davea@sgi.com +------------------------------------------------------------- diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/COPYING --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/COPYING Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,37 @@ + + +The files: + libdwarf.h + dwarf.h + and all the .h and .c files in this implementation of + libdwarf are copyrighted according to the file + LIBDWARFCOPYRIGHT (which mentions the LGPL version 2.1). + The full text of the LGPL 2.1 is provided in LGPL.txt + + +The dwarf documentation: + dwarf.v2.mm and its postscript form and its + indexes are copyright Unix International (UI is now defunct). + One presumes XOPEN owns the copyright now. In any case copying + and revision without fee is permitted (see the + copyright in the document). + +The libdwarf documentation: + libdwarf2.1.mm + is based on material submitted to the UI PLSIG as proposed + interfaces for dwarf, but completely rewritten. + Copyright ownership is therefore SGI (but see the document for details) + and it seems clear that the intent was there was to be free + copying with no fees. + + libdwarf2p.1.mm + is documentation of a set of interfaces + (not part of the UI PLSIG proposals) + and the document was written from scratch at SGI. + Copyright ownership is therefore SGI (but see the document for details) + and it seems clear that the intent was there was to be free + copying with no fees. + +$Source: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/libdwarf/RCS/COPYING,v $ +$Revision: 1.2 $ +$Date: 2001/01/16 17:08:36 $ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/ChangeLog --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/ChangeLog Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,217 @@ +2007-12-09 DavidAnderson + * dwarf_sort_line.c dwarf_print_lines.c darf_frame.c: Forgot + to commit yesterday. + Today's commit includes renaming _dwarf_fde_section_offset + _dwarf_cie_section_offset, _dwarf_print_lines, _dwarf_ld_sort_lines + to dwarf_* name while retaining support for the now obsolete + _dwarf_* form. +2007-12-08 DavidAnderson + * config.h.in, configure.in: Latest linux libelf.h requires + _GNU_SOURCE to get off64_t defined so dwarfdump compiles. + Only define _GNU_SOURCE if libelf.h defines off64_t. + Regenerated configure. + * config.guess, config.sub: Updated to 2.61 + * acconfig.h: Deleted, removing autoconf complaint. +2007-11-14 David Anderson + * dwarf_frame2.c (gnu_aug_encodings): Now allows 'S' augmentation + character in eh_frame. +2007-10-16 David Anderson + * dwarf_alloc.c: Reformat a comment. + * dwarf_die_deliv.c (dwarf_siblingof): When there is no trailing + null-DIE in the section, ensure we don't test the contents + of a byte past section end. + * dwarf_frame.c: Changed spelling of a local variable + so it is easier to grep for and to read. + * dwarf_macro.c (free_macro_stack): Was free()ing memory that + _dwarf_get_alloc() had supplied, which could lead to core dump. + Fixed potential memory leaks (said leaks only possible with an + error in the macro data, not with valid macro section + data). +2007-10-15 David Anderson + * dwarf_alloc.c: The code supporting the special build + flag DWARF_SIMPLE_MALLOC + was broken and could coredump libdwarf + (which did not affect normal use of libdwarf). + * dwarf_opaque.h: Remove the field de_simple_malloc_current + as it is no longer used. + +2007-09-04 David Anderson + * pro_forms.c: Add commentary relating to the + recent DWARF4 DW_AT_high_pc change. + Correct FSF address. + * libdwarf2p.1.mm: Document dwarf_add_AT_dataref() + and dwarf_add_AT_ref_address(). + * libdwarf2p.1.pdf: Regenerate. + * dwarf.h: Update FSF address. + * dwarf_opaque.h: Add DWARF4 entry (version stamp). + Update FSF address. + * dwarf_die_deliv.c: Add check for .debug_info version 4 + (version stamp). Update FSF address. + * libdwarf.h pro_macinfo.h pro_line.h dwarf_incl.h + pro_alloc.h pro_section.h libdwarfdefs.h pro_util.h + dwarf_vars.h dwarf_funcs.h pro_error.h dwarf_alloc.h pro_arange.h + dwarf_arange.h pro_die.h dwarf_global.h pro_expr.h + pro_reloc_stream.h pro_incl.h pro_encode_nm.h + dwarf_line.h pro_frame.h pro_opaque.h dwarf_error.h + dwarf_base_types.h dwarf_abbrev.h pro_types.h pro_reloc_symbolic.h + dwarf_weaks.h dwarf_util.h dwarf_loc.h malloc_check.h + dwarf_die_deliv.h acconfig.h dwarf_frame.h dwarf_macro.h + pro_reloc.h dwarf_types.h + pro_funcs.c Makefile.in pro_forms.c pro_line.c + dwarf_print_lines.c pro_alloc.c pro_init.c dwarf_addr_finder.c + pro_section.c dwarf_form.c dwarf_query.c dwarf_vars.c + dwarf_pubtypes.c dwarf_frame3.c dwarf_funcs.c pro_error.c + pro_arange.c dwarf_alloc.c dwarf_arange.c pro_die.c + dwarf_sort_line.c dwarf_global.c dwarf_init_finish.c pro_weaks.c + pro_pubnames.c pro_expr.c pro_reloc_stream.c pro_finish.c + pro_encode_nm.c dwarf_line.c pro_frame.c dwarf_error.c + dwarf_abbrev.c pro_types.c dwarf_leb.c pro_reloc_symbolic.c + dwarf_string.c pro_vars.c dwarf_line2.c dwarf_weaks.c + dwarf_frame2.c dwarf_util.c dwarf_loc.c LIBDWARFCOPYRIGHT + malloc_check.c dwarf_die_deliv.c dwarf_frame.c dwarf_stubs.c + dwarf_macro.c pro_reloc.c dwarf_types.c pro_macinfo.c: + Update FSF address. +2007-07-26 David Anderson + * pro_frame.c: Added commentary about some missing DWARF3 support. + * dwarf_srclines_dealloc.c: File unused, now deleted. +2007-07-04 David Anderson + * libdwarf.h: dwarf_get_loclist_entry() is implemented, + removed the erroneous 'unimplemented' comment. + * libdwarf2.1.mm: Improved the dwarf_get_loclist_entry() + documentation. + * libdwarf2.1.pdf: regenerated + * dwarf_loclist_entry.c: Removed from distribution, the + source has nothing of interest. + +2007-07-03 David Anderson + * libdwarf.h: Add declaration of dwarf_loclist_from_expr(); + * dwarf_loc.c: Implement dwarf_loclist_from_expr() and add + sign-extension macro calls to case DW_OP_const4s numbers. + Removed unused local variables. + * dwarf_form.c: Removed unused local variables. + * libdwarf2.1.mm: Document dwarf_loclist_from_expr(). + * libdwarf2.1.pdf: Regenerated. +2007-07-01 David Anderson + * dwarf_frame2.c: Add commentary. + * dwarf_frame.c: Add in block_len for DW_CFA_val_expression + so libdwarf does not get confused by this frame expression + operator. Thanks to Cristian Vlasceanu for providing + a test case. +2007-06-29 David Anderson + * README: added a note that a few warnings about conversions + from pointer to integer are normal at libdwarf compile time. +2007-05-25 David Anderson + * dwarf_frame2.c (_dwarf_get_fde_list_internal): + Correct cie-list-creation so it adds to the tail of the list. + gcc 4.1.2 generates cie-use in an order the code did + not properly handle. +2007-05-08 David Anderson + * Makefile.in: Now generates pdf files. + * mips_extensions.mm: The only changes were to eliminate + unsupported macro (.PM) and to try to get correct output + from groff. No technical content change intended. + The pdf/postscript output remains a little odd though. + * libdwarf2.1.mm: Remove troff comment line. +2007-04-18 Chris Quenelle + * dwarf_addr_finder.c: repaired comment + * dwarf_form.c: add support for DW_AT_SUN_func_offsets + * pro_alloc.c: add memory block tracking to find and fix + lingering allocations. This is more important for very large + and intensive compiles. + * pro_die.c: Implement "markers" which are a generic way to + do things like relocations. You can set a marker on any + die, and when dwarf is produced in binary form, you get back + a list of your markers with the offset of each one in the binary + output. This is used by the Sun compilers to implement die + references that span compile unit blocks. (I may remove this, + it might be unused code related to partial_units and comdat + support) + * pro_die.c: Also check for loops in the die relationships so + that if you add a child twice, or other errors, you won't get + an infinite loop or a crash. Also start passing a DBG structure + to all allocation calls to help with memory block tracking. + * pro_expr.c: Add a public function to "reset" an expr. This + allows the same expr object to be reused over and over to save + memory if you're creating many many expressions for a location list. + * pro_finish.c: Free any left over blocks when the user calls + dwarf_producer_finish. + * pro_forms.c: More support for compressed integer blocks. Modify + error diagnostics so that user-defined attributes can be any type. + Add support for dwarf_add_AT_ref_address which is just like + dwarf_add_AT_address, only it produces a DW_FORM_ref_addr instead + of DW_FORM_addr. This is needed for cross-CU die pointers. + * pro_incl.h: add macros to control the spelling of relocation types. + * pro_init.c: use new macros to control reloc types + * pro_line.h: correct minimum instruction length on x86 + * pro_opaque.h: add support for markers (see above) and also ability + have libdwarf tell the caller where the string constants are so + that they can be recorded as strings in case the binary output of libdwarf + needs to be converted back into assembly. That's what + Dwarf_P_Per_Sect_String_Attrs is about. + Remove de_mem_list as it is never used. + * pro_reloc_stream.c: repair prototype and comment for + _dwarf_pro_reloc_name_stream64, and use relocation type macros. + * pro_section.c: support for markers (see above) and for tracking + inline string attributes. Add code to sort the attributes so that + abbreviation table entries will be reduced. Change treatment of + DW_FORM_ref_addr to be more correct. Some support for packing + in the middle of sections, this will probably be removed. + Also pass DBg structure to more allocations. + * pro_util.h: relocation type values can't be zero. +2007-04-10 David Anderson for free() + declaration. + * dwarf_print_lines.c pro_section.c dwarf_query.c dwarf_alloc.c + dwarf_arange.c dwarf_sort_line.c dwarf_global.c dwarf_line.c + dwarf_abbrev.c dwarf_srclines_dealloc.c dwarf_frame2.c + dwarf_util.c dwarf_loc.c dwarf_die_deliv.c dwarf_frame.c + dwarf_macro.c: indent run with standard libdwarf options. + +2007-02-20 David Anderson + * dwarf_error.c, libdwarf.h: added + DW_DLE_FRAME_REGISTER_COUNT_MISMATCH. + * dwarf_frame.c (_dwarf_exec_frame_instr): removed references + to compile-time constants for register table size. Now uses + run-time-chosen sizes. Now uses heap for reg table instead + of stack. Now uses SIMPLE_ERROR_RETURN macro to simplify + the code. +2006-11-08 David Anderson + * pro_expr.c (dwarf_add_expr_gen): DW_OP_deref_size, + DW_OP_xderef_size, and DW_OP_pick were incorrect, missing + & operator. Would coredump. Thanks to Alan Chambers for mentioning + the coredump. +2006-09-26 David Anderson + * dwarf_die_deliv.c (dwarf_offdie): Now returns the + correct die (worked before, almost always, but worked by accident). + Thanks to Mattias Lindblad for supplying a test case. +2006-09-01 David Anderson + * libdwarf2.1.mm (dwarf_loclist_n): Minor refinement + of the description. + * libdwarf2.1.ps: regenerated +2006-08-31 David Anderson + * libdwarf2.1.mm (dwarf_loclist_n): A location expression + sets ld_lopc to 0, ld_hipc to all-bits-on, and this + is now documented. + * libdwarf2.1.ps: regenerated +2006-06-14 David Anderson + * dwarf_opaque.h dwarf_frame.h dwarf_frame.c + dwarf_init_finish.c dwarf_frame2.c: Corrected handling + of eh_frame zP encoding. + Thanks to Cristi Vlasceanu for noticing it was broken. + * Makefile.in: remove libdwarf.so in 'clean' rule. + Thanks to Cristi Vlasceanu for noticing it was missing. +2006-04-28 David Anderson + * dwarf_frame.c: Changed local variable type to + avoid compiler warning. +2006-04-21 David Anderson + * dwarf_frame.c: Initialized local to 0, wrong value. + Thanks to Cristi Vlasceanu for noticing. +2006-04-18 David Anderson + * All *.c: Ran indent so all c files follow a standard look. +2006-04-16 David Anderson + * dwarf.h: Remove #if 0 around some #defines, it is ok to + leave the defines visible (the defines are HP extensions). + * libdwarf.h: Add new dwarf3 interface to frames. + (which actually is also a better interface to dwarf2 info, + not strictly for dwarf3). + * dwarf_alloc.c: Add 'constructor/destructor' pointers + to the initialization table so we can handle a more + flexible (dwarf3) frame interface.Call the functions + at the appropriate times. + * dwarf_frame.c: Using macro FDE_NULL_CHECKS_AND_SET_DBG + reduce duplicate coding.Internal code now handles dwarf2 + and dwarf3 and interfaces to exported interfaces appropriately. + * dwarf_frame.h: Alter internal struct to handle frames more flexibly. + * dwarf_frame2.c: Remove unused local variable. + * dwarf_init_finish.c: Add initialization of new Dwarf_Debug + struct entries allowing handling + of run-time-config of frame info. + * dwarf_loc.c: Add DWARF3 operators, such as DW_OP_call4. + * dwarf_opaque.h: Declaration of new Dwarf_Debug struct + entries allowing handling of run-time-config of frame info. + * pro_expr.c: Add entries allowing creation of DWARF3 DW_OP + such as call2. + * pro_section.c: Change crucial code handling section lengths, + using a macro BEGIN_LEN_SIZE to clarify and correct a few places. +2006-03-31 David Anderson + * libdwarf.h: Added dwarf_get_fde_info_for_cfa_reg3() prototype + preparing for dwarf3 frame interface. + * dwarf_frame.c: Now uses separate rule, not DW_FRAME_CFA_COL, + to record CFA. + * dwarf_frame.h: Add commentary on frame access. +2006-03-30 David Anderson + * Makefile.in configure.in: Adding --enable-shared --enable-nonshared + --disable-shared and --disable-nonshared. + * configure: regenerated with 2.59 autoconf. + * README: Added explanation on changing dwarf.h libdwarf.h. +2006-03-29 David Anderson + * dwarf_print_lines.c dwarf_sort_line.c: Clean up initialization + code for line table reading. When returning rules table + data to caller ensure fully filled out yet no overrun + (handling case where rules table sizes not defined identically + by caller and library). + * dwarf.h: New commentary on ABI/register-number issues. + * libdwarf.h: New commentary on ABI/register-number issues. +2006-03-26 David Anderson + * dwarf_line.c: file_entry_count local was not initialized. + Initialized some locals at declaration. + Thanks to Mikael Vidstedt for noticing. +2006-03-23 David Anderson + * dwarf_error.c: added error strings for codes 200,201 + * dwarf_line.c dwarf_line.h dwarf_print_lines.c dwarf_sort_line.c: Moved + line prefix reading to a common routine, filling in a new internal + struct to make it simple. Removed much duplicate code. + Added more support for dwarf3 line table standard opcodes. + Now prints details (with -v -v) of standard opcodes it + does not understand (if any present). +2006-03-13 David Anderson + * dwarf.h: add ALTIUM #defines (extensions to dwarf) + * libdwarf.h: Alter arguments to new + functions dwarf_get_fde_augmentation_data() and + dwarf_get_cie_augmentation_data() used by GNU eh_frame. + * dwarf_frame.h: Add new fields so we can handle GNU eh_frame. + * dwarf_frame.c: Remove erroneous load_sections calls (wrong for eh_frame + data) and correct the new dwarf_get_fde_augmentation_data() and + dwarf_get_cie_augmentation_data() implementation. + * dwarf_frame2.c: Implement support for GNU eh_frame. + * dwarf_line.h: Correct handling of DWARF3 opcode base check. + * dwarf_line.c: Add new macro use to get DWARF3 opcode base handling correct. + * dwarf_print_lines.c: Add new macro use to get DWARF3 opcode base handling correct. + * dwarf_sort_lines.c: Add new macro use to get DWARF3 opcode base handling correct. +2006-03-08 David Anderson + * dwarf_frame2.c: ensure local variables initialized + to avoid coredump. +2006-03-08 David Anderson + * dwarf_die_deliv.c: Remove Richard Stukey's -1 and + replace with a simpler more complete fix. +2006-03-07 David Anderson + * Makefile.in: Add dwarf_line2.c dwarf_frame3.c to files to build. + * dwarf_addr_finder.c: Add comments about file purpose. + * dwarf_frame.c: Move IRIX specific function out of this file. + * dwarf_frame3.c: Move IRIX specific function to this new file. + * dwarf_frame.h: Add interface declaration. + * dwarf_line.c: Move IRIX specific function out of this file. + * dwarf_line2.c: Move IRIX specific function to this new file. + * dwarf_line.h: Add interface declaration. + * dwarf_frame2.c: Altered comments so indent handles them better, + ran indent. + +2006-03-07 David Anderson + * dwarf_die_deliv.c (dwarf_siblingof): -1 to point to end of cu, + not one-past-end. With thanks to Richard Stuckey. + * libdwarf2.1.mm: document existing function dwarf_get_fde_exception_info() + * dwarf_frame.h: Add new internal interfaces. + * dwarf_frame.c: Remove cie/fde reader to dwarf_frame2.c. + * dwarf_frame2.c: Contains heavily refactored cie/fde reader, + preparing for eh_frame support and avoids some searching + in fde creation. Removes duplicated code into new + internal functions. + * Makefile.in: Adding comment about flag for malloc_checking + code. Add dwarf_frame2.c to source list. + * libdwarf.h: added declarations for eh_frame information, though + these are not yet supported. + * dwarf.h: Added defines for eh_frame information, though these + are not yet used. +2006-02-23 David Anderson + * dwarf_line.h dwarf_line.c: added dwarf_line_srcfileno() + to complement dwarf_lineno. + * libdwarf2.1.mm: document dwarf_line_srcfileno(). + +2005-11-25 David Anderson + * dwarf.h: Now matches 2005 DWARF3 public review document. + +2005-11-08 David Anderson + * dwarf_alloc.c, dwarf_init_finish.c, dwarf_sort_line.c, malloc_check.c: + remove malloc.h include, it is not needed, stdlib.h suffices. + +2005-10-24 David Anderson + * dwarf.h: Updated to match DWARF3 public review document. + +2005-10-03 David Anderson + * dwarf_alloc.c: Change some entries to BASE_ALLOC. + * dwarf_global.h: Add argument to interface so we do not + universally use DW_DLA_GLOBAL, but cater to compatibility. + * dwarf_funcs.c, dwarf_global.c, dwarf_weaks.c, + dwarf_funcs.c, dwarf_types.c: Restored use of DW_DLA_* + instead of universally using DW_DLA_GLOBAL. + * dwarf_pubtypes.c: added comments about DW_DLA_GLOBAL use. +2005-08-01 David Anderson + * malloc_check.c: Moved the #ifdef WANT_LIBBDWARF_MALLOC_CHECK + down after #includes so the test is meaningful. +2005-07-15 David Anderson + * libdwarf.h: New DW_DLA codes and full .debug_types support added. + new dealloc functions declared. + * Makefile.in: Add dwarf_pubtypes.o (.debug_pubtypes support). + * dwarf_abbrev.c: Add dealloc() calls where needed. + * dwarf_alloc.c: Add dwarf_malloc_check calls, rename and + update _DW_RESERVE to DW_RESERVE, make hash table declaration + in array more readable. Add optional final dealloc loop. + * dwarf_alloc.h: Increase the index array to add .debug_pubtypes + support. + * dwarf_base_types.h: Increase the index array to add .debug_pubtypes + support. + * dwarf_die_deliv.c: Add dealloc calls to get full dealloc. + * dwarf_error.c: Document new error codes for .debug_pubtypes. + * dwarf_init_finish.c: Add .debug_pubtypes support, add + dwarf_malloc_check_complete() call for alloc checking. + * dwarf_form.c: Document dwarf_formstring() use. + * dwarf_frame.c: Add dwarf_fde_cie_list_dealloc() for + complete dealloc. + * dwarf_global.h: Add _dwarf_internal_globals_dealloc + declaration for libdwarf-internal use. + * dwarf_global.c dwarf_funcs.c dwarf_types.c dwarf_vars.c + dwarf_weaks.c: Add new dealloc public routines for + complete dealloc and add .debug_pubtypes support. + * dwarf_pubtypes.c: Support for .debug_pubtypes. + * dwarf_malloc_check.h dwarf_malloc_check.c : New checking + for complete accurate dealloc (off by default). + * dwarf_opaque.h: Add internal .debug_pubtypes support. + * libdwarf2.1.mm: Document new dealloc code, correct + dwarf_formstring documentation. + +2005-07-14 David Anderson + * dwarf_line.c: Added dwarf_srclines_dealloc and call it + for dwarf_srclines output. Does complete deallocation, + unlike previous method, which was incomplete deallocation. + Thanks to Alan Alexander for pointing out there was + incomplete deallocation. + * dwarf_print_lines.c: remove references and allocation + of line_context. Memory was leaking due to unreferenced + variable. + * libdwarf2.1.mm: Document new dwarf_srclines_dealloc() + deallocation routine for dwarf_srclines(). + +2005-07-13 David Anderson + * dwarf_init_finish.c (dwarf_init): if _dwarf_setup() fails, + free elf resources with elf_end() call. + Thanks to Cristi Vlasceanu for pointing out that a memory + leak existed here. + +2005-06-13 David Anderson + * dwarf_frame.c (_dwarf_exec_frame_instr): Corrected test + so that .o files (pre-relocation) are less likely to generate + DW_DLE_DF_NEW_LOC_LESS_OLD_LOC error. Renamed local variable + for better readability. +2005-04-13 David Anderson + * dwarf_error.c: Error codes 194 and 195 were missing + strings, added them to table. + * dwarf_frame.c: Check for newer gcc .eh_frame + augmentation strings and avoid trying to handle these + for now. + * dwarf_global.c: Add an error check for + pubnames-style sections for bad offset. + * dwarf_init_finish.c: Add dwarf_get_section_max_offsets() + to allow clients to do additional error checking. + This code will have to change again, so leaving it + undocumented. As written it's not useful for COMDAT + style DWARF sections. + * libdwarf.h: Added prototype for dwarf_get_section_max_offsets(). + +2005-03-31 David Anderson + * mips_extensions.mm: Documented the libexc/.debug_funcnames + dependency and the 64bit-offset DWARF extension. + * mips_extensions.ps: Regenerated. + +2005-03-21 David Anderson + * dwarf_line.c: Added commentary. + * libdwarf2.1.mm: Documented dwarf_lineendsequence() better. + * libdwarf2.1.ps: Regenerated. + * libdwarf.h: Added DW_DLE_FRAME_AUGMENTATION_UNKNOWN as + error code 195. + * dwarf_init_finish.c: Corrected comment spelling. + * dwarf_frame.h dwarf_frame.c: Added handling for + much (but not all) of gcc 3.3 gcc 3.4 .eh_frame + 'z' augmentation. Gives error on attempting + to get z augmentation data since such is not + completely handled. + +2005-03-18 David Anderson + * dwarf_frame.h dwarf_frame.c: The gcc .eh_frame + info did not print correctly so we now access the + correct section data so it prints. Still no support + for dwarf3 frame operators. + * dwarf_macro.c: Detect end-of-macros properly + (stopped too soon before). + +2005-02-14 David Anderson + * pro_incl.h: Added #elif defined(HAVE_LIBELF_H) + enabling build on a platform missing normal elf.h. + +2005-02-11 David Anderson + * dwarf_base_types.h: Added DW_CIE_VERSION3 define. + * dwarf_die_deliv.c: Allowed CURRENT_VERSION_STAMP3. + * dwarf_frame.c: Allowed DW_CIE_VERSION3. + * dwarf_frame.h: Define DW_DEBUG_FRAME_VERSION3. + * dwarf_line.c: Allow CURRENT_VERSION_STAMP3. + * dwarf_line.h: Add lc_version_number to line structure. + * dwarf_opaque.h: Add CURRENT_VERSION_STAMP3 and comment showing + version numbers (DWARF3 vs DWARF2) by DWARF section. + +2004-11-21 David Anderson + * configure.in libdwarfdefs.h: Now tests more precisely for __uint32_t + and __uint64_t (previous test was not sufficient for debian/mips). + Regenerated configure config.h.in. + +2004-10-28 David Anderson + * LIBDWARFCOPYRIGHT Makefile.in NEWS config.h dwarf_abbrev.c + dwarf_abbrev.h dwarf_addr_finder.c dwarf_alloc.c dwarf_alloc.h + dwarf_arange.c dwarf_arange.h dwarf_base_types.h dwarf_die_deliv.c + dwarf_die_deliv.h dwarf_error.c dwarf_error.h dwarf_form.c + dwarf_frame.c dwarf_frame.h dwarf_funcs.c dwarf_funcs.h + dwarf_global.c dwarf_global.h dwarf_incl.h dwarf_init_finish.c + dwarf_leb.c dwarf_line.c dwarf_line.h dwarf_loc.c dwarf_loc.h + dwarf_macro.c dwarf_macro.h dwarf_opaque.h dwarf_print_lines.c + dwarf_query.c dwarf_sort_line.c dwarf_string.c dwarf_stubs.c + dwarf_types.c dwarf_types.h dwarf_util.c dwarf_util.h + dwarf_vars.c dwarf_vars.h dwarf_weaks.c dwarf_weaks.h + libdwarfdefs.h pro_alloc.c pro_alloc.h pro_arange.c pro_arange.h + pro_die.c pro_die.h pro_encode_nm.c pro_encode_nm.h pro_error.c + pro_error.h pro_expr.c pro_expr.h pro_finish.c pro_forms.c + pro_frame.c pro_frame.h pro_funcs.c pro_funcs.h pro_incl.h + pro_init.c pro_line.c pro_line.h pro_macinfo.c pro_macinfo.h + pro_opaque.h pro_pubnames.c pro_pubnames.h pro_reloc.c + pro_reloc.h pro_reloc_stream.c pro_reloc_stream.h pro_reloc_symbolic.c + pro_reloc_symbolic.h pro_section.c pro_section.h pro_types.c + pro_types.h pro_util.c pro_util.h pro_vars.c pro_vars.h + pro_weaks.c pro_weaks.h: Copyright update with + 2004 and new SGI official address. + +2004-10-26 David Anderson + * acconfig.h: removed. Was old style autoconf usage. + * configure.in: Updated AC_DEFINE usage, adding args 2 & 3. + * config.guess: Updated. timestamp='2004-06-11'. + * config.sub: Updated. timestamp='2004-03-12'. + * configure config.h.in: regenerated with autoconf 2.58. + +2004-06-09 David Anderson + * dwarf_frame.c (_dwarf_exec_frame_instr): + Was not setting ru_offset to 1 in DW_CFA_def_cfa_offset + case, now it does. + +2004-02-24 David Anderson + * dwarf_frame.c (_dwarf_exec_frame_instr): + DW_CFA_def_cfa_register case, was setting offset, which + is incorrect. Thanks to Tom Hughes + for pointing this out. + +2004-02-03 David Anderson + * dwarf_util.h: DECODE_LEB128_UWORD DECODE_LEB128_SWORD + were simply wrong if Dwarf_Word or + Dwarf_Sword longer than 4 bytes. Upper bits left random. + Large values not extracted correctly. + +2004-01-15 David Anderson + * dwarf_alloc.c pro_alloc.c pro_init.c: changing BSD-ish bzero() + to posix-standard memset() calls. + * configure.in: remove bstring.h test, add alloca.h test. + No longer useing bzero, some environments have alloca + in malloc.h, no alloca.h. If neither exist + it's up to you to deal with it. + * dwarf_line.c dwarf_print_lines.c dwarf_sort_line.c: Test + HAVE_ALLOCA_H + * configure config.h.in: regenerated + +2003-12-31 David Anderson + * dwarf_init_finish.c: added #error to detect and describe + absence of libelf.h. + * README: Added mention of libelf.h requirement, minor + cleanout of obsolete comments, added configure example. + * Makefile.in: Removed bogus LIBS line, updated copyright date. + * acconfig.h: Updated copyright date. + * config.guess config.sub: new versions from automake-1.6. + * config.h.in configure: Regenerated. + +2003-12-15 David Anderson + * dwarf_init_finish.c (_dwarf_setup): test for (section_size) + was wrong for eh_frame section. Changed this one to + (section_size == 0) so it is like all the others testing + section_size. Thanks to David Mosberger + for pointing out this inconsistency. + +2003-12-08 David Anderson + * dwarf_line.h: reference in comment to li_dbg meant to + refer to li_offset. Corrected and amplified comment. + +2003-10-06 David Anderson + * dwarf_abbrev.c dwarf_die_deliv.c dwarf_form.c dwarf_loc.c + dwarf_util.c: applied indent(1). + +2003-10-02 David Anderson + * dwarf_loc.c: Implemented dwarf_get_loclist_entry(), + implemented new dwarf_loclist_n() fully implementing + loclist support. + * dwarf_stubs.c: removed dwarf_get_loclist_entry stub. + * libdwarf2.1.mm: Documented dwarf_loclist_n() and + updated documentation on dwarf_loclist(). + +2003-09-29 David Anderson + * dwarf_abbrev.c: Ensure the .debug_abbrev section is loaded. + * dwarf_arange.c dwarf_global.c: Recent dwarf committee + discussions have revealed we were wrong in not allowing + padding in aranges. + * dwarf_die_deliv.c dwarf_query.c: handle DW_FORM_indirect. + * dwarf_form.c: Add dwarf_whatform_direct() so folks + can report on DW_FORM_indirect use. + Fill in new Dwarf_Locdesc fields. + * dwarf_loc.c: Handle .debug_loc partially. + Fill in new Dwarf_Locdesc fields. + Load .debug_loc if not present and if it's needed. + * dwarf_opaque.h: Added ar_attribute_form_direct field + so we can report DW_FORM_indirect + in libdwarf-using code (where such wants to). + * dwarf_util.c: Don't confuse DW_FORM_indirect uleb length + with other lengths. + * libdwarf2.1.mm: Document new function dwarf_whatform_direct() + Not needed by ordinary clients, just for clients + wanting to print certain debug info. + +2003-04-15 Brian Ford + * configure.in (AC_C_BIGENDIAN): Move after AC_PROG_CC so a proper + working compiler is used for the test. + +2003-01-21 David Anderson + * dwarf_die_deliv.c (dwarf_next_cu_header, dwarf_offdie): + Add calls to dwarf_load_object() to load .debug_info, + .debug_abbrev + * dwarf_init_finish.c (_dwarf_setup): Remove calls to + dwarf_load_object for .debug_info, .debug_abbrev sections. + * dwarf_opaque.h: Add new fields to Dwarf_Debug so + we don't need to pre-load .debug_info, .debug_abbrev + * dwarf_util.h: Fix READ_AREA_LENGTH macro so it uses + only length itself to determine which format the + length is. + +2003-01-14 David Anderson + * dwarf_loc.c: Made comment at head of dwarf_loclist() + a bit clearer. + +2002-11-22 Tom Hughes + * dwarf_macro.c: Corrected bugs in macro-info functions. + +2002-10-29 David Anderson + * dwarf_init_finish.c: The libelf_sgi mods + left a HAVE_ELF64_GETSHDR ifdef in the wrong place + so folks without Elf64 could not build. Fixed. + +2002-10-21 David Anderson + * dwarf_form.c: the form_ref functions were failing to + add in cc_extension_size when checking for offset + legality. Thanks to Kelly O'Hair + for pointing out the 4 places this was wrong. + Used cu_context local pointer to avoid numerous + double indirections. + +2002-08-14 David Anderson + * dwarf_string.c (dwarf_get_str): Return + DW_DLV_NO_ENTRY when offset is just at the end of the + sections, making it possible to use dwarf_get_str + to print the section independently. + * libdwarf2.1.mm, libdwarf2.1.ps: Document the + revised dwarf_get_str interface (which was not + fully thought thru before). + * dwarf_line.c (dwarf_srcfiles): Avoid core dump + when DW_AT_comp_dir absent (it's not required). + + +2002-07-31 David Anderson + * pro_types.c (_dwarf_transform_simplename_to_disk): correct + generation of .debug_info size field. + Thanks to Kelly O'Hair for pointing out + the bug. + +2002-05-23 Daniel Gohman + * dwarf_init_finish.c: Add support for using SGI's + ELF library as an alternative to using AT&T-style + libelf. + Add a new function _dwarf_load_section to handle + loading of sections. + * dwarf_opaque.h: Add entries to Dwarf_Debug_s to + store section indicies. + * most consumer files: Load sections on demand so + that unneeded sections don't get loaded. + * dwarf_init_finish.c: Fixed an incorrect check for + duplicate .eh_frame sections. + +2002-04-25 Kelly O'Hair + * pro_section.c (_dwarf_pro_generate_debuginfo): add + required dwarf2 sec 7.5.3 trailing null byte + to .debug_abbrev per compilation-unit. + +2002-03-31 David Anderson + * dwarf_abbref.c (dwarf_get_abbrev): change + DW_DLE_DEBUG_ABBREV_NULL to DW_DLE_DWARF_ABBREV_NULL. + Former was wrong code. + * libdwarf2.1.mm: correct argument reference, returned_abbrev + not returned_fde in dwarf_get_abbrev discussion. + +2002-03-07 David Anderson + * libdwarf.h: added struct Elf declaration + to reduce dependency on header include ordering. + +2002-02-11 David Anderson + * libdwarf2.1.mm libdwarf2.1.ps: + dwarf_offdie can return DW_DLV_NO_ENTRY and that + is now documented. + * dwarf_loc.c: if the length of a location description + is zero that is ok, not an error. dwarf2 sec 2.4.1. + +2002-01-10 David Anderson + * dwarf_opaque.h, dwarf_init_finish.c: if libdwarf does + the elf_begin() it must also do the elf_end() to + avoid a memory leak, and now does this correctly. + +2002-01-10 David Anderson + * dwarf_init_finish.c: Using a variable to + hold ELF_C_READ_MMAP. Really motivated by + code not added to this source. + * dwarf_die_deliv.c: Added comments, moved + a couple variables to local scope from function scope. + + * dwarf.h: Added some #defines which were specified in the Dwarf + 2.1 Dwarf draft 5 (now called dwarf 3 draft 5). + +2001-09-18 David Anderson davea@sgi.com + * all files: applied gnu indent with + -bad -bap -nbbo -br -ce -brs + -l72 -lc72 -hnl -nprs + -fca -i4 -lp -psl -npcs + Code should use this set in libdwarf. + + +2001-08-21 "kelly o'hair" + * pro_section.c: If one called dwarf_add_file_decl() + or dwarf_add_directory_decl() but never added a line, + .debug_line was not produced. This was a mistake, + as if any file or directory was provided .debug_line + should be produced. + +2001-08-06 davea@sgi.com + * libdwarf2.1.mm: documented dwarf_dealloc rules + more clearly. (.ps updated too) + * mips_extensions.mm: documented the way SGI + gets frame stack pointer out of debug_frame. + (.ps updated too) + +2001-06-14 davea@sgi.com + * dwarf_leb.c: changed around where bytes counted in + _dwarf_decode_s_leb128 so it's easier to tell it is correct. + And removed one loop completely: it was + an early attempt at performance improvement and + is no longer relevant. + + * dwarf_global.c: added new + dwarf_get_cu_die_offset_given_cu_header_offset function + to get CU die offset (as the long name says). + A variety of functions return cu-header-offsets, so + this is useful at times. + Used locals to reduce the number of indirections + and make things easier to follow. + + * dwarf_arange.c: added new dwarf_get_arange_cu_header_offset + function so dwarfdump could print the cu header offset + (which appears in the arange headers). + + * libdwarf2.1.mm: documented the above new functions. + +2001-06-07 davea@sgi.com + * dwarf_leb.c: shift operator was not being applied + to full size of Dwarf_Signed/Unsigned for 64bit + Dwarf_Signed/Unsigned (ILP32 compile) so + large numbers not decoded if signed. + * pro_encode_nm.c: added {} in a couple if/else + for 'clarity' and to make inserting debug printf easier. + * pro_expr.c: Added comments explaining why possible + compiler (gcc) warnings are ok, the result is safe. + +2001-05-30 davea@sgi.com + * pro_reloc_stream.c: Wrote Set_REL32_info and + Set_REL64_info macros + from generic ELF abi documents to make use acceptable + when IRIX elfaccess.h is not available. + +2001-05-30 "kelly o'hair" + * Makefile.in: was missing pro_macinfo.o + pro_encode_nm.o dwarf_macro.o from the OBJS list. + +2001-05-22 davea@sgi.com + * dwarf_frame.c, pro_expr.c: Added comments on why + casts are safe in spite of gcc warnings (4 places total). + +2001-05-18 Dan Gritter + * dwarf_loc.c DW_OP_bregx operands are unsigned + reg num followed by signed offset. + +2001-04-11 David Anderson + * dwarf_die_deliv.c: check for 0 abbreviation code + and return a 'no entry' return value when found. + (normal dwarf2, 0 means no DIE, the end of some set of DIEs.) + +2001-01-16 David Anderson + + * pro_die.c: set ar_reloc_len field + in all cases. + +2000-12-14 David Anderson + + * dwarf_frame.h: clarified some comments. + +2000-12-14 Ulrich Drepper + + * dwarf_line.c: Now sets DW_LNE_end_sequence to + default_is_stmt, the correct value, not is_stmt. + + +2000 Aug 24 davea@sgi.com + dwarf_error.c: a dwarf_init() failure resulted in this + using a static Dwarf_Error struct. And dwarf_dealloc + did not deal properly with that. + dwarf_alloc.c dwarf_alloc.h: these had DYNAMIC_CHUNK protected code + which was never used. Deleted the unused code. Added a small + comment (hopefully useful) to dwarf_alloc.h. + + And now deals correctly with a null dbg on + DW_DLA_ERROR due to failed + dwarf_init() call (or due to other error in calling + libdwarf that results in libdwarf not knowing the dbg, + a likely far more common case) and frees the memory. + This used to result in chaos (depending on your + luck...). + +2000 Aug 23 davea@sgi.com + libdwarf2.1.mm, ps. Failed to mention that dwarf_finish() + has to be accompanied by elf_end() if dwarf_init() was used + to initialize libdwarf to truly release all stuff. + Added text to dwarf_finish() describing how to do that. +2000 April 14 davea@sgi.com + + dwarf_abbrev.c - 1.22 + - When it is a null abbrev entry, return it correctly so it can be + printed (meaning fill out all the return-parameters so the caller can + do the right thing). + + dwarf_init_finish.c - 1.48 + - For most sections, simply having an empty section (present but empty) + is just fine. There is no reason to register an error in such a case. + + Copyright has changed. See LIBDWARFCOPYRIGHT and NEWS + + dwarfdump/print_die.c - 1.42 + - Explain what combo checker is doing and make it more maintainable (and fix bug which would not be hit, but was real enough). + + dwarfdump/tag_tree.list - 1.2 + - Add valid parent/child relationships so checker does not report valid + entries as bogus. + + dwarf_form.c - 1.26 + - Correct dwarf reader to use appropriate size, not de_length_size. This is part of the handling of the new dwarf2 64bit facilities. I + overlooked this small aspect before in one place + dwarf_query.c - 1.48 + - Use correct size, not de_length_size. For offset size. + libdwarf2.1.mm - 1.41 + - Tried to make frame register output args meaning clearer + libdwarf2.1.ps - 1.19 + - Tried to make frame register output args meaning clearer + pro_forms.c - 1.33 + - Get ref4, not ref8 when generating 32bit dwarf per original dwarf2 + spec. even if pointer size is 64 bits. + pro_init.c - 1.18 + - Get ref4, not ref8 when generating 32bit dwarf per original dwarf2 + spec. even if pointer size is 64 bits. + + +davea@sgi.com + + +2000 March 7 +dwarf_line.c - 1.48 +dwarf_line.h - 1.16 +dwarf_print_lines.c - 1.10 +dwarf_sort_line.c - 1.8 + - Now handles opcode_base of line section to be other than that at + compile time of libdwarf. +Important as the dwarf2 committee is adding a new standard opcode +davea@sgi.com + +2000 Feb 24 +pro_forms.c 1.31 ar_next field not always zeroed before. +Could lead to infinite loop in the producer code. +Now the field is always zeroed. + +Makefile.in - 1.3 Jason Merrill + provided fix so gcc will work on libdwarf +print_sections.c - 1.54 - casts to avoid warnings + +davea@sgi.com + + +1999 Dec 14 +acconfig.h - 1.3 +config.h.in - 1.5 +configure - 1.4 +configure.in - 1.5 + - HAVE_DWARF2_99_EXTENSION HAVE_OLD_DWARF2_32BIT_OFFSET + refinements added. +CHANGES - 1.3 +Makefile.base - 1.98 +NEWS - 1.5 +config.h - 1.4 +config.h.in - 1.4 +configure.in - 1.4 +dwarf_alloc.c - 1.36 +dwarf_arange.c - 1.19 +dwarf_arange.h - 1.6 +dwarf_die_deliv.c - 1.51 +dwarf_frame.c - 1.62 +dwarf_frame.h - 1.23 +dwarf_funcs.c - 1.10 +dwarf_funcs.h - 1.3 +dwarf_global.c - 1.21 +dwarf_global.h - 1.7 +dwarf_init_finish.c - 1.45 +dwarf_line.c - 1.44 +dwarf_opaque.h - 1.52 +dwarf_print_lines.c - 1.8 +dwarf_query.c - 1.45 +dwarf_types.c - 1.10 +dwarf_types.h - 1.3 +dwarf_util.c - 1.40 +dwarf_util.h - 1.22 +dwarf_vars.c - 1.11 +dwarf_vars.h - 1.3 +dwarf_weaks.c - 1.10 +dwarf_weaks.h - 1.3 +libdwarf2.1.mm - 1.40 +libdwarf2.1.ps - 1.18 +pro_arange.c - 1.15 +pro_die.c - 1.23 +pro_frame.c - 1.29 +pro_init.c - 1.15 +pro_macinfo.c - 1.7 +pro_opaque.h - 1.14 +pro_pubnames.c - 1.18 +pro_reloc_stream.c - 1.5 +pro_section.c - 1.70 +pro_section.h - 1.16 +pro_types.c - 1.12 + - Allowing generation of correct dwarf2 with the 1999 64bit dwarf + extension, and reading all forms of dwarf2 compatibly (all 32/64bit + dwarf2 section forms). + +This adds the ability to consume and produce both sgi 64bit +and the new dwarf2 committee-approved 64bit dwarf extension. +As a result of the new dwarf2 stuff , a producer (compiler) +can mix 32 and 64bit dwarf (for a 64bit object) and the +linker will work seamlessly. (as long as section sizes don't +get over 2GBytes). + +And the producer is easily configured to produce mips/sgi style +64bit dwarf or the new form of 64bit dwarf. + +This also eliminates a fair amount of rather silly duplicated code. +davea@sgi.com + + +1999 Nov 4 + +pro_section.c - 1.69 + - A pointer size entity had an offset-size value used at one place. +davea@sgi.com + +1999 Sep 30 +dwarf_arange.c - 1.18 + - Changed // comment to /* */. // failed to compile + with C89 compiler... +davea@sgi.com + + +1999 Sep 29 +Changed all the producer code +substantially to allow generating assembler code +for the dwarf2 (rather similar to what gcc does) +allowing symbolic relocations. +MIPS output still generates the binary form. +davea@sgi.com + + + +1999 Aug 20 +Stan Shebs (shebs@cygnus.com) pointed out that the pro_util.h +use of R_MIPS* was a problem compiling on Sun. +Since the producer code is not really used at present except for +MIPS/sgi, I've added #ifndefs to pro_util.h which provide zero values +when does not provide the macros. +When anyone needs the producer code to actually *work* for non-MIPS +something better will have to be done. + +This has no effect on those simply compiling libdwarf for +use by dwarfdump. +davea@sgi.com + +1999 July 21 +Changed the READ_UNALAGNED macro to call a function +depending on endianness of the host and the object being read. +So all the dwarf_* source changed in a trivial way. +Added support for printing egcs eh_frame section. +Added a local memcpy-like function to do the cross-endian +thing where applicable (called by READ_UNALIGNED macro). +Because the .eh_frame section +after linking can have some zeroed out bytes at the +end of the CIE/FDE data the code looking for CIEs and FDEs +now assumes a zero CIE/FDE length means it has reached +the end of the CIE/FDE data. +davea@sgi.com + + +1999 June 14 + Fred Fish fnf@ninemoons.com contributed + autoconf'ing of the libdwarf and dwarfdump source. + + + mips_extensions.* Documented additional old errors + in the Dwarf Version 2 spec. + + The ChangeLog before this is incomplete. + +------------------------------------------------------------- +Since Oct 95 and before May, 1996 davea@sgi.com David Anderson + +Added the function dwarf_get_cie_of_fde() which makes it possible +to remember a single fde/cie set out of a block usefully. + +Enhanced doc of dwarf_bitoffset() + +Added new function dwarf_global_formref() so all reference +forms can be retrieved. + +Fixed bug in retrieving array bounds: was failing to sign extend +formsdata. + +Added function dwarf_get_fde_info_for_all_regs(), which makes +retrieval of the complete set of registers (as needed by +debuggers and exception handlers) effectively N times faster +than getting them one a time where N is the number of registers. + +Added support for exception table handling (really just support +for a reference to an exception table for c++ exceptions). + +Fixed a bug where useless extra space (several megabytes) +were malloc'ed for the abbreviations table by the libdwarf +consumer code. + +------------------------------------------------------------- +June 10, 1999 + Changelog started. +------------------------------------------------------------- diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/LGPL.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/LGPL.txt Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public 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. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This 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. + + This 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/LIBDWARFCOPYRIGHT --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/LIBDWARFCOPYRIGHT Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,30 @@ + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/Makefile.in Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,194 @@ +# +# +# Copyright (C) 2000,2003,2004,2006 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2.1 of the GNU Lesser General Public License +# as published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, +# USA. + +# +# Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, +# Mountain View, CA 94043, or: +# +# http://www.sgi.com +# +# For further information regarding this notice, see: +# +# http://oss.sgi.com/projects/GenInfo/NoticeExplan +# +# + +# +# Makefile for libdwarf +# This is made very simple so it should work with +# any 'make'. +# + +srcdir = @srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = $(exec_prefix)/bin +libdir = $(exec_prefix)/lib + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +SHELL = /bin/sh +CC = @CC@ +AR = @AR@ +#ARFLAGS = @ARFLAGS@ +RM = rm +RANLIB = @RANLIB@ +DEFS = @DEFS@ +LIBS = @LIBS@ +INCLUDES = -I. -I$(srcdir) +CFLAGS = @CFLAGS@ $(INCLUDES) +# For more checking add -DWANT_LIBBDWARF_MALLOC_CHECK=1 to CFLAGS +LDFLAGS = @LDFLAGS@ + + +BUILD_BASE = . + +OBJS= dwarf_abbrev.o \ + dwarf_alloc.o \ + dwarf_arange.o \ + dwarf_die_deliv.o \ + dwarf_error.o \ + dwarf_form.o \ + dwarf_frame.o \ + dwarf_frame2.o \ + dwarf_frame3.o \ + dwarf_funcs.o \ + dwarf_global.o \ + dwarf_init_finish.o \ + dwarf_line.o \ + dwarf_line2.o \ + dwarf_loc.o \ + dwarf_query.o \ + dwarf_string.o \ + dwarf_stubs.o \ + dwarf_pubtypes.o \ + dwarf_types.o \ + dwarf_util.o \ + dwarf_leb.o \ + dwarf_vars.o \ + dwarf_weaks.o \ + dwarf_addr_finder.o \ + dwarf_sort_line.o \ + dwarf_print_lines.o \ + dwarf_macro.o \ + malloc_check.o \ + pro_alloc.o \ + pro_arange.o \ + pro_die.o \ + pro_encode_nm.o \ + pro_error.o \ + pro_expr.o \ + pro_finish.o \ + pro_forms.o \ + pro_funcs.o \ + pro_frame.o \ + pro_init.o \ + pro_line.o \ + pro_reloc.o \ + pro_reloc_stream.o \ + pro_reloc_symbolic.o \ + pro_pubnames.o \ + pro_section.o \ + pro_types.o \ + pro_vars.o \ + pro_macinfo.o \ + pro_weaks.o + + +all: @build_shared@ @build_nonshared@ + +libdwarf.a: $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +libdwarf.so: $(OBJS) + $(CC) $(CFLAGS) -shared $(OBJS) -o $@ + +none: + echo "do nothing" + +# +# The following are very SGI-centric +# psroff is just a troff formatter. +# the .mm files are in ATT/USL/USG mm form. +# + +docbld:pdfbld +pdfbld: libdwarf2.1.pdf libdwarf2p.1.pdf dwarf.v2.pdf index.v2.pdf mips_extensions.pdf +#Oriented to using gsroff now. +TROFF=/usr/bin/groff +TROFFDEV="-T ps" +TROFFDEV= +PSTOPDF=/usr/bin/ps2pdf +# pr expands tabs to spaces: this avoids problems with tab +# interpretation + +# The warning about 'cant break line' is a too-long line used +# in the table of contents. +# Ignore the warning (and those like it). +libdwarf2.1.pdf: $(BUILD_BASE)/libdwarf2.1.mm + -pr -t -e $(BUILD_BASE)/libdwarf2.1.mm \ + | tbl | $(TROFF) $(TROFFDEV) -mm >libdwarf2.1.ps + $(PSTOPDF) libdwarf2.1.ps libdwarf2.1.pdf + +libdwarf2p.1.pdf: $(BUILD_BASE)/libdwarf2p.1.mm + -pr -t -e $(BUILD_BASE)/libdwarf2p.1.mm \ + | tbl | $(TROFF) $(TROFFDEV) -mm >libdwarf2p.1.ps + $(PSTOPDF) libdwarf2p.1.ps libdwarf2p.1.pdf + +# At present, the newIndex is not usable: we have no tools +# to build a new index page at the moment. + +dwarf.v2.pdf: $(BUILD_BASE)/dwarf.v2.mm + -pic $(BUILD_BASE)/dwarf.v2.mm \ + | tbl | $(TROFF) $(TROFFDEV) -mm >dwarf.v2.ps 2> newIndex + $(PSTOPDF) dwarf.v2.ps dwarf.v2.pdf + +# the index is only useful till the document changes: it is +# not autmatically correct. It was prepared by tools internal +# to USL/Novell + +index.v2.pdf: index.v2.mm + -pic index.v2.mm | tbl | $(TROFF) $(TROFFDEV) -mm >index.v2.ps + $(PSTOPDF) index.v2.ps index.v2.pdf + + +mips_extensions.pdf: mips_extensions.mm + -pr $(TROFFDEV) -e mips_extensions.mm | tbl | \ + $(TROFF) $(TROFFDEV) -mm >mips_extensions.ps + $(PSTOPDF) mips_extensions.ps mips_extensions.pdf + +clean: + rm -f *.o libdwarf.a + rm -f libdwarf.so + +distclean: clean + rm -f config.status config.log config.cache config.h + +shar: + @echo "shar not set up yet" +dist: + @echo "dist not set up yet" diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/NEWS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/NEWS Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,239 @@ +December 8, 2007 + Had to add an ugly configure conditional as libelf has + unconditional use of off64_t in recent libelf.h +July 3, 2007 + A new interface function, dwarf_loclist_from_expr(), + allows easy extraction of dwarf expression bytes from + expressions in frame data. +May 8, 2007 + Now documents released as .mm and .pdf (no longer as .ps). +May 7, 2007 + Incorporates Sun Microsystems extensions to dwarf.h and + to the consumer and producer libraries. The changes + include corrections so the producer library cleans up it's memory + use on a call to dwarf_producer_finish(dbg). + Thanks to Chris Quenelle of Sun for these contributions. + +March 20, 2007 + nroff/troff and the AT&T -mm package are not widely available, + so now the Makefile refers to groff, which works quite nicely. + +February 20, 2007 + Documented libdwarf thread safety in README. + Fixed memory leak in dwarf macro reading code. + Removed use of static data in dwarf macro + reading code: now uses stack/heap (for + thread safety). + +February 9, 2007 + Maintenance of libdwarf is now outside SGI + as David Anderson has left SGI. + +March 29, 2006 + The March 27, 2006 version accomodates DWARF3. + Some people have been using the library without + altering dwarf.h, libdwarf.h to accomodate + large numbers of registers. This exposed a bug + (an off-by-one error) but also makes it clear + additional documentation is needed. So + in libdwarf large new comments near 'TARGET DEPENDENCY' + attempt to explain better. +Oct 03, 2005 + The July version had an incompatible interface: old + dealloc code did not always work right. The incompatibility + is now fixed and the new features remain. + +July 15, 2005 + New optional alloc-check code optionally checks all + allocated memory is freed (malloc_check.h malloc_check.c) + Various new dealloc routines written as the previous approach + of letting client code do detailed dealloc turned out not + to dealloc all memory. + To get the new checking you must manually change a line + in malloc_check.h and rebuild libdwarf. + + +Mar 31, 2005 + Documented the libexc.so/.debug_funcnames + dependency and the 64bit-offset DWARF extension in + mips_extentions.{mm,ps}. + +Mar 21, 2005 + gcc 3.3 and 3.4 .eh_frame 'z' augmentations are not handled + correctly, so libdwarf gives an error when attempting to + print such. gcc 2 'eh' augmentation is simpler and + prints correctly. (.eh_frame is a GNU section, + not DWARF2/3, and what is recorded in .eh_frame is not + specified by DWARF2/3, though .eh_frame does resemble + DWARF2/3 .debug_frame). + + +Oct 28, 2004 + Updated contact address in copyright: SGI moved 1/4 mile + in 2003 to a new address: 1500 Crittenden Lane. + + Documented additional vendor extensions. + +Oct 27, 2004 + Added known vendor extensions to dwarf2/3 to dwarf.h + HP, GNU, PGI and UPC extensions are now recorded. + Recorded vendor extensions from Concurrent. + +Feb 3, 2004 + If 'Dwarf_Word' is 64 bits, two macros reading leb numbers + fail to initialize upper bits of the values read. + First noticed with bogus line numbers printing from dwarfdump. + Now we use already-existing functions, avoiding the problem. + +Oct 02, 2003 + Support .debug_loc section fully. + +Sept 29, 2003 + Support DW_FORM_indirect properly. + Supports loclists in part (but not multiple loclist entries yet). + Support 'padding bytes' at end of .debug_arange and + .debug_pubnames and .debug_pubtypes per CU + (recent dwarf committee email made it clear this is appropriate). + +May 23, 2002 + Libdwarf now asks for sections only when they are + used, so that unneeded sections aren't loaded. + Support for using SGI's ELF library as an alternative to + using AT&T libelf-style has been added (the SGI ELF + library is presently only available internally to SGI). + +Jan 10, 2002 + Fixed memory leak in dwarf_finish(). + +Aug 21, 2001 + If one called dwarf_add_file_decl() + or dwarf_add_directory_decl() but never added a line, + .debug_line was not produced. This was a mistake, + as if any file or directory was provided .debug_line + should be produced. Now it is produced. + +June 14, 2001 + Given a cu header offset, it was not easy to derive the + CU header DIE offset. Created the new + function dwarf_get_cu_die_offset_given_cu_header_offset() + do get the CU header DIE offset. + Added the function dwarf_get_arange_cu_header_offset() + so the cu header offset could be retrieved from .debug_aranges + information. + +June 07, 2001 + Major bug in dwarf_leb.c decoding large integers + (Dwarf_Signed 64 bit where library is compiled in ILP32) + found and fixed. + +May 21, 2001 + Some small fixes have been found by various folks, + so it seems time to prepare a new source release. + See ChangeLog for details. + +April 15, 2000 + The libdwarf copyright has changed to + version 2.1 of the GNU Lesser General Public License. + Anyone holding a version of libdwarf that was published + before this new copyright is allowed to use + the copyright published in that earlier libdwarf source + on the earlier source + or to use + this new copyright on the earlier source, + at their option. + + +December 08, 1999 + The dwarf committee has adopted the offset-extension + proposal. This allows compatibly emitting + dwarf with 64bit offsets. + + The dwarf reader now automatically figures out which is in use. + The dwarf writer configures itself at the time the + writer initialization routine is called, though + the writer is restricted, at libdwarf + compile time, to one of + mips/sgi pure 32/pure 64 offsets/pointers. + + 32bit offsets only (per dwarf 2.0.0 and cygnus) + + 32bit offsets with extension to 64bit offsets + allowed (the offset-extension newly passed). + + In addition, a great deal of duplicate code + for the sgi .debug_weaknames, .debug_funcnames, + .debug_varnames and .debug_typenames sections has + been removed: a single set of functions does the real work now. + +Sept 29, 1999 + Just found out that cygnus is, on 64bit targets, generating + 32bit offsets (as elf32 has, for example) with 64 bit + pointers (in references to text and data). + Whereas sgi has always generated 64bit dwarf with + 64 bit offsets (as in elf64) and 64bit pointers for + 64bit pointer objects. + I'll call the sgi approach 64-bit and the cygnus approach + 32bit-offsets. + + Cygnus is following the DWARF2 spec as written, so they are + right in doing only 32bit-offsets. + + Folks at sgi (including me) think that, as for elf64, + the offsets in dwarf for 64bit pointer-apps should be + 64 bits. We think it is only a matter of time + before we really *need* 64bit offsets and when that happens + it will be on an important app. Disk space is cheap, + so lets just go 64 bit on 64bit apps (such as ia64 apps) + to avoid a future problem. + I(davea@sgi.com) think the 'pointer-size' references in the dwarf + spec were really written for 64-bit pointer apps. + I don't recall serious consideration of 64bit pointer + apps in the committee deliberations (I did miss + a couple of meetings) and think 64bit offsets + are consistent with dwarf2, even though the speci + was not written for such. We think true full 64 bit + dwarf2 is the right way to go (the spec changes + are obvious: file and section offsets become 64bit + with 64bit pointer objects. + + MIPS/SGI is definitely 64-bit offsets for 64 bit objects, + cygnus is definitely 32bit-offsets for earlier 64bit pointer + environments. + + At any rate, now the dwarf reader allows and accomodates + both and the dwarf producer also accomodates both. + Some tweaking of the pro_init.c or dwarf_init_finish.c + files may be necessary in future: no other changes should + be needed to accomodate the two 64bit approaches, as + the library (and dwarfdump) now deal with both forms. + + +August 20, 1999 + Added some #ifndef/#define to pro_util.h to let libdwarf build + on more hosts. (since those hosts don't need the producer + code, AFAIK, zero values suffice for missing #defines.) + +July 21, 1999 + Now reader transparently reads either-endianness data + from an either-endianness object. + Updated dwarf.h and libdwarf.h to recognize + GNU egcs dwarf extensions and to print the egcs eh_frame + section. + +June 10, 1999 + gnu configure version of libdwarf made available for the + first time. + Still allows only same-endian-as-host in objects. + +August, 1994 + libdwarf source made available for ftp on sgigate.sgi.com + /ftp/pub + +June, 1994 + Consumer interface changed completely, following + "Candy Machine Interfaces" chapter from + "Writing Solid Code" by Steve Maguire (Microsoft Press). + +April, 1993 + Initial version of libdwarf for dwarf version 2 + written at sgi. diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/README Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,136 @@ +To build libdwarf.a, type + ./configure + make + +To use dwarf or libdwarf, you may want to install dwarf.h and +libdwarf.h somewhere convenient, and you may need the libdwarf +in the accompanying libdwarf directory + +Multi Threading, or using threads with libdwarf (Thread Safety): + Nothing in libdwarf does any locking. Every Dwarf_Debug + (such as returned by dwarf_init()) is fully independent + of all other Dwarf_Debug-s. However, calls to libdwarf can + change a Dwarf_Debug. So it is unsafe to have two different + threads accessing a single Dwarf_Debug simultaneously. + It is therefore sufficient to ensure than any one Dwarf_Debug + is only accessed from a single thread. + +Warnings like + "warning: cast from pointer to integer of different size" +at compile time are to be expected in dwarf_frame.c and +dwarf_frame2.c. Do not be alarmed. + +If your headers are not in the expected places, +use the configure script to access them (and to add other ld +or C flags). +For example + ./configure CPPFLAGS="-I/home/davea/inc" CFLAGS="-I/home/davea/inc" +Set both CFLAGS and CPPFLAGS so that configure works properly. + +It is now possible to request shared library build with + --enable-shared +(--enable-nonshared is on by default). + +TARGET DEPENDENCIES of .debug_frame: +dwarf.h + These should be revised if you have more than the defined + 63 'normal' registers. It's not harmful to have these too large! + Too small will lead to errors reading .debug_frame and .eh_frame. + DW_FRAME_HIGHEST_NORMAL_REGISTER + DW_FRAME_LAST_REG_NUM + + These you might revise, but can safely ignore if simply + using dwarfdump. If using the producer code you will want + to get these exactly right for your architecture. + DW_FRAME_RA_COL + DW_FRAME_STATIC_LINK + DW_FRAME_CFA_COL + +libdwarf.h + The DW_FRAME_REG_INITIAL_VALUE #define should be set to + the value approprate to your archtecture. See libdwarf.h + for details. + + If DW_REG_TABLE_SIZE is not set large enough attempts to + fill in the .debug_frame tables will get an error. + Should be at least as large as DW_FRAME_LAST_REG_NUM. + If it's too large nothing is harmed (but some extra space taken + at run time). + + +The .debug_frame is so very architecture dependent +and because the host (where libdwarf/dwarfdump are executed) +and target (the objects read) could be different. +It's currently not supported to have dwarfdump/libdwarf determine +the architecture on-the-fly and do-the-right-thing. +Just setting DW_FRAME_LAST_REG_NUM and DW_FRAME_HIGHEST_NORMAL_REGISTER +and DW_REG_TABLE_SIZE high enough will likely suffice for most +purposes and most compilers/architectures.. +See comments in dwarf.h/libdwarf.h. + +It's perfectly safe to ignore the above suggestions as long +as libdwarf does not get a DW_DLE_DF_REG_NUM_TOO_HIGH error. +(which would only happen on reading .debug_frame or .eh_frame data). + +If you intend to use the libdwarf dwarf-producer code +for .debug_frame information +you must do a thorough analysys and revise dwarf.h +substantially to match the output target archtecture. + +In general, in the producer code, numbers are copied from and +to integers with memcpy(). In case of endianness problems, +constants set in dwarf_producer_init() can fix the problems. +If one wants to produce a *different-endian* output the best +solution is to change the integer memcpy calls to call thru a +new dbg-based function pointer and have it 'do the right thing' +to adjust endianness. Set the function pointer correctly in +dwarf_producer_init() and the rest of the code will just call +thru the function pointer. Tedious work to find and change the +memcpy calls to be dbg->de_memcpy(), but once done the code is +no longer endian dependent (right now there is no way to ask +for cross-endian: a new flag needed or ?). + +leb128 numbers are endian-independent, so nothing need be +done with those for cross-endian support (the storage +of leb128 on disk is always little-endian). + +The .ps files are postscript. So those who cannot deal with mm +format files but do have a postscript printer (or have +ghostscript) can print the documents. +This form was chosen before pdf format existed... + +libdwarf2.1.ps documents a way for a debugger to read dwarf information. +libdwarf2p.1.ps documents a way for a compiler to generate dwarf information. +dwarf.v2.ps documents Dwarf Version 2. +index.v2.ps is an index to dwarf.v2.ps. +indexDW.v2 is a plain text index of dwarf #defines to dwarf.v2.ps +mips_extensions.ps documents the mips/sgi extensions to dwarf. + +The commands used to generate the postscript were: + pr -t -e libdwarf2.1.mm | tbl | psroff -t -mm >libdwarf2.1.ps + pr -t -e libdwarf2p.1.mm | tbl | psroff -t -mm >libdwarf2p.1.ps + pic dwarf.v2.mm | tbl | psroff -t -mm >dwarf.v2.ps 2> newIndex + pic index.v2.mm | tbl | psroff -t -mm >index.v2.ps + +pic is a picture processing tool (ATT command). +tbl is a table-processing tool. +(part of Documentor's Work Bench on ATT-like systems). +tbl and pic are available on linux. + +psroff is a name for a troff-like processor, part of +Documentor's Work Bench on IRIX. Substitute a +troff-like or nroff-like processor. + +The index.v2.mm was generated by the dwarf-document writer +using some local ATT/USL tools (which SGI does not have, so +there is no way I know of to regenerate this). + +To use dwarf or libdwarf, you may want to install dwarf.h and +libdwarf.h somewhere convenient. + +You will also need libelf (libelf.a and/or libelf.so) and +libelf.h installed. These are available from GNU repositories. + +$Source: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/libdwarf/RCS/README,v $ +$Revision: 1.10 $ +$Date: 2006/03/30 18:04:52 $ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/bldDWindex.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/bldDWindex.sh Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,24 @@ +sed -n -e '/^%%Page.*/p' -e '/.*DW_.*/p' . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + x86:Interix*:[3456]*) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T:Interix*:[3456]* | authenticamd:Interix*:[3456]*) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/config.h.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/config.h.in Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,109 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_ALLOCA_H + +/* Define 1 if want producer to build with 32/64bit section offsets per dwarf3 + */ +#undef HAVE_DWARF2_99_EXTENSION + +/* Define to 1 if the elf64_getehdr function is in libelf.a. */ +#undef HAVE_ELF64_GETEHDR + +/* Define to 1 if the elf64_getshdr function is in libelf.a. */ +#undef HAVE_ELF64_GETSHDR + +/* Define to 1 if you have the header file. */ +#undef HAVE_ELFACCESS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ELF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBELF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBELF_LIBELF_H + +/* Define 1 if off64 is defined via libelf with GNU_SOURCE. */ +#undef HAVE_LIBELF_OFF64_OK + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define 1 if want producer to build with only 32bit section offsets per + strict dwarf2 */ +#undef HAVE_OLD_DWARF2_32BIT_OFFSET + +/* Define 1 if plain libelf builds. */ +#undef HAVE_RAW_LIBELF_OK + +/* Define 1 if R_IA_64_DIR32LSB is defined (might be enum value). */ +#undef HAVE_R_IA_64_DIR32LSB + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IA64_ELF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* See if __uint32_t is predefined in the compiler. */ +#undef HAVE___UINT32_T + +/* Define 1 if __uint32_t is in sgidefs.h. */ +#undef HAVE___UINT32_T_IN_SGIDEFS_H + +/* Define 1 if sys/types.h defines __uint32_t. */ +#undef HAVE___UINT32_T_IN_SYS_TYPES_H + +/* See if __uint64_t is predefined in the compiler. */ +#undef HAVE___UINT64_T + +/* Define 1 if is in sgidefs.h. */ +#undef HAVE___UINT64_T_IN_SGIDEFS_H + +/* Define 1 if sys/types.h defines __uint64_t. */ +#undef HAVE___UINT64_T_IN_SYS_TYPES_H + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/config.sub --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/config.sub Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1619 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2006-11-07' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# 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 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/configure --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/configure Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,5247 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.59. +# +# Copyright (C) 2003 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="libdwarf.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA RANLIB ac_ct_RANLIB AR ac_ct_AR build_shared build_nonshared LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-shared build shared library libdwarf.so (default is NO) + --enable-nonshared build archive library libdwarf.a (default is YES) + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF + +Copyright (C) 2003 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + ac_config_headers="$ac_config_headers config.h" + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 +echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 +if test "${ac_cv_c_bigendian+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # See if sys/param.h defines the BYTE_ORDER macro. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + # It does; now see whether it defined to BIG_ENDIAN or not. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_bigendian=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +# It does not; compile a test program. +if test "$cross_compiling" = yes; then + # try to guess the endianness by grepping values into an object file + ac_cv_c_bigendian=unknown + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; +short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; +void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } +short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } +int +main () +{ + _ascii (); _ebcdic (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then + ac_cv_c_bigendian=yes +fi +if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int +main () +{ + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long l; + char c[sizeof (long)]; + } u; + u.l = 1; + exit (u.c[sizeof (long) - 1] == 1); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_bigendian=yes +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 +echo "${ECHO_T}$ac_cv_c_bigendian" >&6 +case $ac_cv_c_bigendian in + yes) + +cat >>confdefs.h <<\_ACEOF +#define WORDS_BIGENDIAN 1 +_ACEOF + ;; + no) + ;; + *) + { { echo "$as_me:$LINENO: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&5 +echo "$as_me: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} + { (exit 1); exit 1; }; } ;; +esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + +if test $ac_cv_c_compiler_gnu = yes; then + echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5 +echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6 +if test "${ac_cv_prog_gcc_traditional+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_pattern="Autoconf.*'x'" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +Autoconf TIOCGETP +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then + ac_cv_prog_gcc_traditional=yes +else + ac_cv_prog_gcc_traditional=no +fi +rm -f conftest* + + + if test $ac_cv_prog_gcc_traditional = no; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +Autoconf TCGETA +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then + ac_cv_prog_gcc_traditional=yes +fi +rm -f conftest* + + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5 +echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6 + if test $ac_cv_prog_gcc_traditional = yes; then + CC="$CC -traditional" + fi +fi + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + echo "$as_me:$LINENO: result: $AR" >&5 +echo "${ECHO_T}$AR" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 +echo "${ECHO_T}$ac_ct_AR" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + AR=$ac_ct_AR +else + AR="$ac_cv_prog_AR" +fi + + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + + + + +for ac_header in alloca.h elf.h elfaccess.h libelf.h libelf/libelf.h sys/types.h sys/ia64/elf.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +echo "$as_me:$LINENO: checking for elf64_getehdr in -lelf" >&5 +echo $ECHO_N "checking for elf64_getehdr in -lelf... $ECHO_C" >&6 +if test "${ac_cv_lib_elf_elf64_getehdr+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lelf $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char elf64_getehdr (); +int +main () +{ +elf64_getehdr (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_elf_elf64_getehdr=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_elf_elf64_getehdr=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_elf_elf64_getehdr" >&5 +echo "${ECHO_T}$ac_cv_lib_elf_elf64_getehdr" >&6 +if test $ac_cv_lib_elf_elf64_getehdr = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ELF64_GETEHDR 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for elf64_getshdr in -lelf" >&5 +echo $ECHO_N "checking for elf64_getshdr in -lelf... $ECHO_C" >&6 +if test "${ac_cv_lib_elf_elf64_getshdr+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lelf $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char elf64_getshdr (); +int +main () +{ +elf64_getshdr (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_elf_elf64_getshdr=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_elf_elf64_getshdr=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_elf_elf64_getshdr" >&5 +echo "${ECHO_T}$ac_cv_lib_elf_elf64_getshdr" >&6 +if test $ac_cv_lib_elf_elf64_getshdr = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ELF64_GETSHDR 1 +_ACEOF + +fi + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +__uint32_t p; p = 3; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE___UINT32_T 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +__uint64_t p; p = 3; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE___UINT64_T 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ + __uint32_t p; p = 3; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE___UINT32_T_IN_SYS_TYPES_H 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ + __uint64_t p; p = 3; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE___UINT64_T_IN_SYS_TYPES_H 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ + int p; p = R_IA_64_DIR32LSB; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_R_IA_64_DIR32LSB 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include + +int +main () +{ + int p; p = 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_RAW_LIBELF_OK 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#define _GNU_SOURCE +#include + +int +main () +{ + off64_t p; p = 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBELF_OFF64_OK 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ + __uint32_t p; p = 27; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE___UINT32_T_IN_SGIDEFS_H 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ + __uint64_t p; p = 27; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE___UINT64_T_IN_SGIDEFS_H 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ + __uint64_t p; p = 27; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE___UINT64_T_IN_SGIDEFS_H 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + + +build_nonshared=libdwarf.a + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + build_shared=libdwarf.so + +else + build_shared=none + +fi; +# Check whether --enable-nonshared or --disable-nonshared was given. +if test "${enable_nonshared+set}" = set; then + enableval="$enable_nonshared" + build_nonshared=libdwarf.a + + build_nonshared=none + +fi; + + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ + int p; p = R_IA_64_DIR32LSB; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_OLD_DWARF2_32BIT_OFFSET 1 +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DWARF2_99_EXTENSION 1 +_ACEOF + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + + ac_config_files="$ac_config_files Makefile" +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + + + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@CPP@,$CPP,;t t +s,@EGREP@,$EGREP,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@AR@,$AR,;t t +s,@ac_ct_AR@,$ac_ct_AR,;t t +s,@build_shared@,$build_shared,;t t +s,@build_nonshared@,$build_nonshared,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + # Do quote $f, to prevent DOS paths from being IFS'd. + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/configure.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/configure.in Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,85 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(libdwarf.h) +AC_CONFIG_HEADER(config.h) + +AC_PROG_CC +AC_C_BIGENDIAN +AC_GCC_TRADITIONAL +AC_PROG_INSTALL +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(AR, ar) + +dnl AC_ARFLAGS + +AC_CHECK_HEADERS(alloca.h elf.h elfaccess.h libelf.h libelf/libelf.h sys/types.h sys/ia64/elf.h) + +AC_CHECK_LIB(elf,elf64_getehdr, + AC_DEFINE(HAVE_ELF64_GETEHDR,1, + [Define to 1 if the elf64_getehdr function is in libelf.a.])) +AC_CHECK_LIB(elf,elf64_getshdr, + AC_DEFINE(HAVE_ELF64_GETSHDR,1, + [Define to 1 if the elf64_getshdr function is in libelf.a.])) +AC_TRY_COMPILE( , __uint32_t p; p = 3; ,AC_DEFINE(HAVE___UINT32_T,1, + [See if __uint32_t is predefined in the compiler.])) +AC_TRY_COMPILE( , __uint64_t p; p = 3; ,AC_DEFINE(HAVE___UINT64_T,1, + [See if __uint64_t is predefined in the compiler.])) +AC_TRY_COMPILE([#include ],[ __uint32_t p; p = 3;] , + AC_DEFINE(HAVE___UINT32_T_IN_SYS_TYPES_H,1, + [Define 1 if sys/types.h defines __uint32_t.])) +AC_TRY_COMPILE([#include ],[ __uint64_t p; p = 3;] , + AC_DEFINE(HAVE___UINT64_T_IN_SYS_TYPES_H,1, + [Define 1 if sys/types.h defines __uint64_t.])) +dnl checking for ia 64 types, which might be enums, using HAVE_R_IA_64_DIR32LSB +dnl to stand in for a small set. +AC_TRY_COMPILE([#include ],[ int p; p = R_IA_64_DIR32LSB;] , + AC_DEFINE(HAVE_R_IA_64_DIR32LSB,1, + [Define 1 if R_IA_64_DIR32LSB is defined (might be enum value).])) + +AC_TRY_COMPILE([ +#include +],[ int p; p = 0; ] , + AC_DEFINE(HAVE_RAW_LIBELF_OK,1, + [Define 1 if plain libelf builds.])) +AC_TRY_COMPILE([ +#define _GNU_SOURCE +#include +],[ off64_t p; p = 0;] , + AC_DEFINE(HAVE_LIBELF_OFF64_OK,1, + [Define 1 if off64 is defined via libelf with GNU_SOURCE.])) + +dnl the existence of sgidefs.h does not prove it's truly SGI, nor +dnl prove that __uint32_t or __uint64_t is defined therein. +AC_TRY_COMPILE([#include ],[ __uint32_t p; p = 27;] , + AC_DEFINE(HAVE___UINT32_T_IN_SGIDEFS_H,1, + [Define 1 if __uint32_t is in sgidefs.h.])) +AC_TRY_COMPILE([#include ],[ __uint64_t p; p = 27;] , + AC_DEFINE(HAVE___UINT64_T_IN_SGIDEFS_H,1, + [Define 1 if __uint64_t is in sgidefs.h.])) +AC_TRY_COMPILE([#include ],[ __uint64_t p; p = 27;] , + AC_DEFINE(HAVE___UINT64_T_IN_SGIDEFS_H,1, + [Define 1 if is in sgidefs.h.])) + +AC_SUBST(build_shared,[]) +AC_SUBST(build_nonshared,[libdwarf.a]) +AC_ARG_ENABLE(shared,AC_HELP_STRING([--enable-shared], + [build shared library libdwarf.so (default is NO)]), + [ AC_SUBST(build_shared,[libdwarf.so]) ], + [ AC_SUBST(build_shared,[none]) ]) +AC_ARG_ENABLE(nonshared,AC_HELP_STRING([--enable-nonshared], + [build archive library libdwarf.a (default is YES)]), + [ AC_SUBST(build_nonshared,[libdwarf.a]) ] + [ AC_SUBST(build_nonshared,[none]) ]) + + +dnl Just assume, if old ia64 R_IA_64_DIR32LSB name present, +dnl compatibility with cygnus before +dnl HAVE_DWARF2_99_EXTENSION defined. +dnl Only applies to producer code, as consumer adapts itself. +dnl This is not the right test, really. +AC_TRY_COMPILE([#include ],[ int p; p = R_IA_64_DIR32LSB;] , + AC_DEFINE(HAVE_OLD_DWARF2_32BIT_OFFSET,1, + [Define 1 if want producer to build with only 32bit section offsets per strict dwarf2] ), + AC_DEFINE(HAVE_DWARF2_99_EXTENSION,1, + [Define 1 if want producer to build with 32/64bit section offsets per dwarf3] )) + +AC_OUTPUT(Makefile) diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1012 @@ +/* + Copyright (C) 2000,2001,2003,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2002,2007 Sun Microsystems, Inc. All rights reserved. + Portions Copyright 2007 David Anderson. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + +#ifndef __DWARF_H +#define __DWARF_H +#ifdef __cplusplus +extern "C" { +#endif + +/* + dwarf.h DWARF debugging information values + $Revision: 1.41 $ $Date: 2006/04/17 00:09:56 $ + + The comment "DWARF3" appears where there are + new entries from DWARF3 as of 2004, "DWARF3f" + where there are new entries as of the November 2005 + public review document and other comments apply + where extension entries appear. + + Extensions part of DWARF4 are marked DWARF4. + + A few extension names have omitted the 'vendor id' + (See chapter 7, "Vendor Extensibility"). Please + always use a 'vendor id' string in extension names. + + Vendors should use a vendor string in names and + whereever possible avoid duplicating values used by + other vendor extensions + +*/ + + +#define DW_TAG_array_type 0x01 +#define DW_TAG_class_type 0x02 +#define DW_TAG_entry_point 0x03 +#define DW_TAG_enumeration_type 0x04 +#define DW_TAG_formal_parameter 0x05 +#define DW_TAG_imported_declaration 0x08 +#define DW_TAG_label 0x0a +#define DW_TAG_lexical_block 0x0b +#define DW_TAG_member 0x0d +#define DW_TAG_pointer_type 0x0f +#define DW_TAG_reference_type 0x10 +#define DW_TAG_compile_unit 0x11 +#define DW_TAG_string_type 0x12 +#define DW_TAG_structure_type 0x13 +#define DW_TAG_subroutine_type 0x15 +#define DW_TAG_typedef 0x16 +#define DW_TAG_union_type 0x17 +#define DW_TAG_unspecified_parameters 0x18 +#define DW_TAG_variant 0x19 +#define DW_TAG_common_block 0x1a +#define DW_TAG_common_inclusion 0x1b +#define DW_TAG_inheritance 0x1c +#define DW_TAG_inlined_subroutine 0x1d +#define DW_TAG_module 0x1e +#define DW_TAG_ptr_to_member_type 0x1f +#define DW_TAG_set_type 0x20 +#define DW_TAG_subrange_type 0x21 +#define DW_TAG_with_stmt 0x22 +#define DW_TAG_access_declaration 0x23 +#define DW_TAG_base_type 0x24 +#define DW_TAG_catch_block 0x25 +#define DW_TAG_const_type 0x26 +#define DW_TAG_constant 0x27 +#define DW_TAG_enumerator 0x28 +#define DW_TAG_file_type 0x29 +#define DW_TAG_friend 0x2a +#define DW_TAG_namelist 0x2b + /* Early releases of this header had the following + misspelled with a trailing 's' */ +#define DW_TAG_namelist_item 0x2c /* DWARF3/2 spelling */ +#define DW_TAG_namelist_items 0x2c /* SGI misspelling/typo */ +#define DW_TAG_packed_type 0x2d +#define DW_TAG_subprogram 0x2e + /* The DWARF2 document had two spellings of the following + two TAGs, DWARF3 specifies the longer spelling. */ +#define DW_TAG_template_type_parameter 0x2f /* DWARF3/2 spelling*/ +#define DW_TAG_template_type_param 0x2f /* DWARF2 spelling*/ +#define DW_TAG_template_value_parameter 0x30 /* DWARF3/2 spelling*/ +#define DW_TAG_template_value_param 0x30 /* DWARF2 spelling*/ +#define DW_TAG_thrown_type 0x31 +#define DW_TAG_try_block 0x32 +#define DW_TAG_variant_part 0x33 +#define DW_TAG_variable 0x34 +#define DW_TAG_volatile_type 0x35 +#define DW_TAG_dwarf_procedure 0x36 /* DWARF3 */ +#define DW_TAG_restrict_type 0x37 /* DWARF3 */ +#define DW_TAG_interface_type 0x38 /* DWARF3 */ +#define DW_TAG_namespace 0x39 /* DWARF3 */ +#define DW_TAG_imported_module 0x3a /* DWARF3 */ +#define DW_TAG_unspecified_type 0x3b /* DWARF3 */ +#define DW_TAG_partial_unit 0x3c /* DWARF3 */ +#define DW_TAG_imported_unit 0x3d /* DWARF3 */ + /* Do not use DW_TAG_mutable_type */ +#define DW_TAG_mutable_type 0x3e /* Withdrawn from DWARF3 by DWARF3f. */ +#define DW_TAG_condition 0x3f /* DWARF3f */ +#define DW_TAG_shared_type 0x40 /* DWARF3f */ +#define DW_TAG_lo_user 0x4080 + +#define DW_TAG_MIPS_loop 0x4081 + +/* HP extensions: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz */ +#define DW_TAG_HP_array_descriptor 0x4090 /* HP */ + +/* GNU extensions. The first 3 missing the GNU_. */ +#define DW_TAG_format_label 0x4101 /* GNU. Fortran. */ +#define DW_TAG_function_template 0x4102 /* GNU. For C++ */ +#define DW_TAG_class_template 0x4103 /* GNU. For C++ */ +#define DW_TAG_GNU_BINCL 0x4104 /* GNU */ +#define DW_TAG_GNU_EINCL 0x4105 /* GNU */ + +/* ALTIUM extensions */ + /* DSP-C/Starcore __circ qualifier */ +#define DW_TAG_ALTIUM_circ_type 0x5101 /* ALTIUM */ + /* Starcore __mwa_circ qualifier */ +#define DW_TAG_ALTIUM_mwa_circ_type 0x5102 /* ALTIUM */ + /* Starcore __rev_carry qualifier */ +#define DW_TAG_ALTIUM_rev_carry_type 0x5103 /* ALTIUM */ + /* M16 __rom qualifier */ +#define DW_TAG_ALTIUM_rom 0x5111 /* ALTIUM */ + +/* The following 3 are extensions to support UPC */ +#define DW_TAG_upc_shared_type 0x8765 /* UPC */ +#define DW_TAG_upc_strict_type 0x8766 /* UPC */ +#define DW_TAG_upc_relaxed_type 0x8767 /* UPC */ + +/* PGI (STMicroelectronics) extensions. */ +#define DW_TAG_PGI_kanji_type 0xa000 /* PGI */ +#define DW_TAG_PGI_interface_block 0xa020 /* PGI */ +/* The following are SUN extensions */ +#define DW_TAG_SUN_function_template 0x4201 /* SUN */ +#define DW_TAG_SUN_class_template 0x4202 /* SUN */ +#define DW_TAG_SUN_struct_template 0x4203 /* SUN */ +#define DW_TAG_SUN_union_template 0x4204 /* SUN */ +#define DW_TAG_SUN_indirect_inheritance 0x4205 /* SUN */ +#define DW_TAG_SUN_codeflags 0x4206 /* SUN */ +#define DW_TAG_SUN_memop_info 0x4207 /* SUN */ +#define DW_TAG_SUN_omp_child_func 0x4208 /* SUN */ +#define DW_TAG_SUN_rtti_descriptor 0x4209 /* SUN */ +#define DW_TAG_SUN_dtor_info 0x420a /* SUN */ +#define DW_TAG_SUN_dtor 0x420b /* SUN */ +#define DW_TAG_SUN_f90_interface 0x420c /* SUN */ +#define DW_TAG_SUN_fortran_vax_structure 0x420d /* SUN */ +#define DW_TAG_SUN_hi 0x42ff /* SUN */ + + +#define DW_TAG_hi_user 0xffff + +#define DW_children_no 0 +#define DW_children_yes 1 + + + +#define DW_FORM_addr 0x01 +#define DW_FORM_block2 0x03 +#define DW_FORM_block4 0x04 +#define DW_FORM_data2 0x05 +#define DW_FORM_data4 0x06 +#define DW_FORM_data8 0x07 +#define DW_FORM_string 0x08 +#define DW_FORM_block 0x09 +#define DW_FORM_block1 0x0a +#define DW_FORM_data1 0x0b +#define DW_FORM_flag 0x0c +#define DW_FORM_sdata 0x0d +#define DW_FORM_strp 0x0e +#define DW_FORM_udata 0x0f +#define DW_FORM_ref_addr 0x10 +#define DW_FORM_ref1 0x11 +#define DW_FORM_ref2 0x12 +#define DW_FORM_ref4 0x13 +#define DW_FORM_ref8 0x14 +#define DW_FORM_ref_udata 0x15 +#define DW_FORM_indirect 0x16 + +#define DW_AT_sibling 0x01 +#define DW_AT_location 0x02 +#define DW_AT_name 0x03 +#define DW_AT_ordering 0x09 +#define DW_AT_subscr_data 0x0a +#define DW_AT_byte_size 0x0b +#define DW_AT_bit_offset 0x0c +#define DW_AT_bit_size 0x0d +#define DW_AT_element_list 0x0f +#define DW_AT_stmt_list 0x10 +#define DW_AT_low_pc 0x11 +#define DW_AT_high_pc 0x12 +#define DW_AT_language 0x13 +#define DW_AT_member 0x14 +#define DW_AT_discr 0x15 +#define DW_AT_discr_value 0x16 +#define DW_AT_visibility 0x17 +#define DW_AT_import 0x18 +#define DW_AT_string_length 0x19 +#define DW_AT_common_reference 0x1a +#define DW_AT_comp_dir 0x1b +#define DW_AT_const_value 0x1c +#define DW_AT_containing_type 0x1d +#define DW_AT_default_value 0x1e +#define DW_AT_inline 0x20 +#define DW_AT_is_optional 0x21 +#define DW_AT_lower_bound 0x22 +#define DW_AT_producer 0x25 +#define DW_AT_prototyped 0x27 +#define DW_AT_return_addr 0x2a +#define DW_AT_start_scope 0x2c +#define DW_AT_bit_stride 0x2e /* DWARF3 name */ +#define DW_AT_stride_size 0x2e /* DWARF2 name */ +#define DW_AT_upper_bound 0x2f +#define DW_AT_abstract_origin 0x31 +#define DW_AT_accessibility 0x32 +#define DW_AT_address_class 0x33 +#define DW_AT_artificial 0x34 +#define DW_AT_base_types 0x35 +#define DW_AT_calling_convention 0x36 +#define DW_AT_count 0x37 +#define DW_AT_data_member_location 0x38 +#define DW_AT_decl_column 0x39 +#define DW_AT_decl_file 0x3a +#define DW_AT_decl_line 0x3b +#define DW_AT_declaration 0x3c +#define DW_AT_discr_list 0x3d +#define DW_AT_encoding 0x3e +#define DW_AT_external 0x3f +#define DW_AT_frame_base 0x40 +#define DW_AT_friend 0x41 +#define DW_AT_identifier_case 0x42 +#define DW_AT_macro_info 0x43 +#define DW_AT_namelist_item 0x44 +#define DW_AT_priority 0x45 +#define DW_AT_segment 0x46 +#define DW_AT_specification 0x47 +#define DW_AT_static_link 0x48 +#define DW_AT_type 0x49 +#define DW_AT_use_location 0x4a +#define DW_AT_variable_parameter 0x4b +#define DW_AT_virtuality 0x4c +#define DW_AT_vtable_elem_location 0x4d +#define DW_AT_allocated 0x4e /* DWARF3 */ +#define DW_AT_associated 0x4f /* DWARF3 */ +#define DW_AT_data_location 0x50 /* DWARF3 */ +#define DW_AT_byte_stride 0x51 /* DWARF3f */ +#define DW_AT_stride 0x51 /* DWARF3 (do not use) */ +#define DW_AT_entry_pc 0x52 /* DWARF3 */ +#define DW_AT_use_UTF8 0x53 /* DWARF3 */ +#define DW_AT_extension 0x54 /* DWARF3 */ +#define DW_AT_ranges 0x55 /* DWARF3 */ +#define DW_AT_trampoline 0x56 /* DWARF3 */ +#define DW_AT_call_column 0x57 /* DWARF3 */ +#define DW_AT_call_file 0x58 /* DWARF3 */ +#define DW_AT_call_line 0x59 /* DWARF3 */ +#define DW_AT_description 0x5a /* DWARF3 */ +#define DW_AT_binary_scale 0x5b /* DWARF3f */ +#define DW_AT_decimal_scale 0x5c /* DWARF3f */ +#define DW_AT_small 0x5d /* DWARF3f */ +#define DW_AT_decimal_sign 0x5e /* DWARF3f */ +#define DW_AT_digit_count 0x5f /* DWARF3f */ +#define DW_AT_picture_string 0x60 /* DWARF3f */ +#define DW_AT_mutable 0x61 /* DWARF3f */ +#define DW_AT_threads_scaled 0x62 /* DWARF3f */ +#define DW_AT_explicit 0x63 /* DWARF3f */ +#define DW_AT_object_pointer 0x64 /* DWARF3f */ +#define DW_AT_endianity 0x65 /* DWARF3f */ +#define DW_AT_elemental 0x66 /* DWARF3f */ +#define DW_AT_pure 0x67 /* DWARF3f */ +#define DW_AT_recursive 0x68 /* DWARF3f */ + + +/* HP extensions. */ +#define DW_AT_HP_block_index 0x2000 /* HP */ + +/* Follows extension so dwarfdump prints the most-likely-useful name. */ +#define DW_AT_lo_user 0x2000 + +#define DW_AT_MIPS_fde 0x2001 /* MIPS/SGI */ +#define DW_AT_MIPS_loop_begin 0x2002 /* MIPS/SGI */ +#define DW_AT_MIPS_tail_loop_begin 0x2003 /* MIPS/SGI */ +#define DW_AT_MIPS_epilog_begin 0x2004 /* MIPS/SGI */ +#define DW_AT_MIPS_loop_unroll_factor 0x2005 /* MIPS/SGI */ +#define DW_AT_MIPS_software_pipeline_depth 0x2006 /* MIPS/SGI */ +#define DW_AT_MIPS_linkage_name 0x2007 /* MIPS/SGI */ +#define DW_AT_MIPS_stride 0x2008 /* MIPS/SGI */ +#define DW_AT_MIPS_abstract_name 0x2009 /* MIPS/SGI */ +#define DW_AT_MIPS_clone_origin 0x200a /* MIPS/SGI */ +#define DW_AT_MIPS_has_inlines 0x200b /* MIPS/SGI */ +#define DW_AT_MIPS_stride_byte 0x200c /* MIPS/SGI */ +#define DW_AT_MIPS_stride_elem 0x200d /* MIPS/SGI */ +#define DW_AT_MIPS_ptr_dopetype 0x200e /* MIPS/SGI */ +#define DW_AT_MIPS_allocatable_dopetype 0x200f /* MIPS/SGI */ +#define DW_AT_MIPS_assumed_shape_dopetype 0x2010 /* MIPS/SGI */ +#define DW_AT_MIPS_assumed_size 0x2011 /* MIPS/SGI */ + +/* HP extensions. */ +#define DW_AT_HP_unmodifiable 0x2001 /* conflict: MIPS */ +#define DW_AT_HP_actuals_stmt_list 0x2010 /* conflict: MIPS */ +#define DW_AT_HP_proc_per_section 0x2011 /* conflict: MIPS */ +#define DW_AT_HP_raw_data_ptr 0x2012 /* HP */ +#define DW_AT_HP_pass_by_reference 0x2013 /* HP */ +#define DW_AT_HP_opt_level 0x2014 /* HP */ +#define DW_AT_HP_prof_version_id 0x2015 /* HP */ +#define DW_AT_HP_opt_flags 0x2016 /* HP */ +#define DW_AT_HP_cold_region_low_pc 0x2017 /* HP */ +#define DW_AT_HP_cold_region_high_pc 0x2018 /* HP */ +#define DW_AT_HP_all_variables_modifiable 0x2019 /* HP */ +#define DW_AT_HP_linkage_name 0x201a /* HP */ +#define DW_AT_HP_prof_flags 0x201b /* HP */ + + +/* GNU extensions. */ +#define DW_AT_sf_names 0x2101 /* GNU */ +#define DW_AT_src_info 0x2102 /* GNU */ +#define DW_AT_mac_info 0x2103 /* GNU */ +#define DW_AT_src_coords 0x2104 /* GNU */ +#define DW_AT_body_begin 0x2105 /* GNU */ +#define DW_AT_body_end 0x2106 /* GNU */ +#define DW_AT_GNU_vector 0x2107 /* GNU */ + + +/* ALTIUM extension: ALTIUM Compliant location lists (flag) */ +#define DW_AT_ALTIUM_loclist 0x2300 /* ALTIUM */ + +/* PGI (STMicroelectronics) extensions. */ +#define DW_AT_PGI_lbase 0x3a00 /* PGI */ +#define DW_AT_PGI_soffset 0x3a01 /* PGI */ +#define DW_AT_PGI_lstride 0x3a02 /* PGI */ + + +/* UPC extension */ +#define DW_AT_upc_threads_scaled 0x3210 /* UPC */ + +/* Sun extensions */ +#define DW_AT_SUN_template 0x2201 /* SUN */ +#define DW_AT_VMS_rtnbeg_pd_address 0x2201 /* VMS */ +#define DW_AT_SUN_alignment 0x2202 /* SUN */ +#define DW_AT_SUN_vtable 0x2203 /* SUN */ +#define DW_AT_SUN_count_guarantee 0x2204 /* SUN */ +#define DW_AT_SUN_command_line 0x2205 /* SUN */ +#define DW_AT_SUN_vbase 0x2206 /* SUN */ +#define DW_AT_SUN_compile_options 0x2207 /* SUN */ +#define DW_AT_SUN_language 0x2208 /* SUN */ +#define DW_AT_SUN_browser_file 0x2209 /* SUN */ +#define DW_AT_SUN_vtable_abi 0x2210 /* SUN */ +#define DW_AT_SUN_func_offsets 0x2211 /* SUN */ +#define DW_AT_SUN_cf_kind 0x2212 /* SUN */ +#define DW_AT_SUN_vtable_index 0x2213 /* SUN */ +#define DW_AT_SUN_omp_tpriv_addr 0x2214 /* SUN */ +#define DW_AT_SUN_omp_child_func 0x2215 /* SUN */ +#define DW_AT_SUN_func_offset 0x2216 /* SUN */ +#define DW_AT_SUN_memop_type_ref 0x2217 /* SUN */ +#define DW_AT_SUN_profile_id 0x2218 /* SUN */ +#define DW_AT_SUN_memop_signature 0x2219 /* SUN */ +#define DW_AT_SUN_obj_dir 0x2220 /* SUN */ +#define DW_AT_SUN_obj_file 0x2221 /* SUN */ +#define DW_AT_SUN_original_name 0x2222 /* SUN */ +#define DW_AT_SUN_hwcprof_signature 0x2223 /* SUN */ +#define DW_AT_SUN_amd64_parmdump 0x2224 /* SUN */ +#define DW_AT_SUN_part_link_name 0x2225 /* SUN */ +#define DW_AT_SUN_link_name 0x2226 /* SUN */ +#define DW_AT_SUN_pass_with_const 0x2227 /* SUN */ +#define DW_AT_SUN_return_with_const 0x2228 /* SUN */ +#define DW_AT_SUN_import_by_name 0x2229 /* SUN */ +#define DW_AT_SUN_f90_pointer 0x222a /* SUN */ +#define DW_AT_SUN_pass_by_ref 0x222b /* SUN */ +#define DW_AT_SUN_f90_allocatable 0x222c /* SUN */ +#define DW_AT_SUN_f90_assumed_shape_array 0x222d /* SUN */ +#define DW_AT_SUN_c_vla 0x222e /* SUN */ +#define DW_AT_SUN_return_value_ptr 0x2230 /* SUN */ +#define DW_AT_SUN_dtor_start 0x2231 /* SUN */ +#define DW_AT_SUN_dtor_length 0x2232 /* SUN */ +#define DW_AT_SUN_dtor_state_initial 0x2233 /* SUN */ +#define DW_AT_SUN_dtor_state_final 0x2234 /* SUN */ +#define DW_AT_SUN_dtor_state_deltas 0x2235 /* SUN */ +#define DW_AT_SUN_import_by_lname 0x2236 /* SUN */ +#define DW_AT_SUN_f90_use_only 0x2237 /* SUN */ +#define DW_AT_SUN_namelist_spec 0x2238 /* SUN */ +#define DW_AT_SUN_is_omp_child_func 0x2239 /* SUN */ +#define DW_AT_SUN_fortran_main_alias 0x223a /* SUN */ +#define DW_AT_SUN_fortran_based 0x223b /* SUN */ + + +#define DW_AT_hi_user 0x3fff + +#define DW_OP_addr 0x03 +#define DW_OP_deref 0x06 +#define DW_OP_const1u 0x08 +#define DW_OP_const1s 0x09 +#define DW_OP_const2u 0x0a +#define DW_OP_const2s 0x0b +#define DW_OP_const4u 0x0c +#define DW_OP_const4s 0x0d +#define DW_OP_const8u 0x0e +#define DW_OP_const8s 0x0f +#define DW_OP_constu 0x10 +#define DW_OP_consts 0x11 +#define DW_OP_dup 0x12 +#define DW_OP_drop 0x13 +#define DW_OP_over 0x14 +#define DW_OP_pick 0x15 +#define DW_OP_swap 0x16 +#define DW_OP_rot 0x17 +#define DW_OP_xderef 0x18 +#define DW_OP_abs 0x19 +#define DW_OP_and 0x1a +#define DW_OP_div 0x1b +#define DW_OP_minus 0x1c +#define DW_OP_mod 0x1d +#define DW_OP_mul 0x1e +#define DW_OP_neg 0x1f +#define DW_OP_not 0x20 +#define DW_OP_or 0x21 +#define DW_OP_plus 0x22 +#define DW_OP_plus_uconst 0x23 +#define DW_OP_shl 0x24 +#define DW_OP_shr 0x25 +#define DW_OP_shra 0x26 +#define DW_OP_xor 0x27 +#define DW_OP_bra 0x28 +#define DW_OP_eq 0x29 +#define DW_OP_ge 0x2a +#define DW_OP_gt 0x2b +#define DW_OP_le 0x2c +#define DW_OP_lt 0x2d +#define DW_OP_ne 0x2e +#define DW_OP_skip 0x2f +#define DW_OP_lit0 0x30 +#define DW_OP_lit1 0x31 +#define DW_OP_lit2 0x32 +#define DW_OP_lit3 0x33 +#define DW_OP_lit4 0x34 +#define DW_OP_lit5 0x35 +#define DW_OP_lit6 0x36 +#define DW_OP_lit7 0x37 +#define DW_OP_lit8 0x38 +#define DW_OP_lit9 0x39 +#define DW_OP_lit10 0x3a +#define DW_OP_lit11 0x3b +#define DW_OP_lit12 0x3c +#define DW_OP_lit13 0x3d +#define DW_OP_lit14 0x3e +#define DW_OP_lit15 0x3f +#define DW_OP_lit16 0x40 +#define DW_OP_lit17 0x41 +#define DW_OP_lit18 0x42 +#define DW_OP_lit19 0x43 +#define DW_OP_lit20 0x44 +#define DW_OP_lit21 0x45 +#define DW_OP_lit22 0x46 +#define DW_OP_lit23 0x47 +#define DW_OP_lit24 0x48 +#define DW_OP_lit25 0x49 +#define DW_OP_lit26 0x4a +#define DW_OP_lit27 0x4b +#define DW_OP_lit28 0x4c +#define DW_OP_lit29 0x4d +#define DW_OP_lit30 0x4e +#define DW_OP_lit31 0x4f +#define DW_OP_reg0 0x50 +#define DW_OP_reg1 0x51 +#define DW_OP_reg2 0x52 +#define DW_OP_reg3 0x53 +#define DW_OP_reg4 0x54 +#define DW_OP_reg5 0x55 +#define DW_OP_reg6 0x56 +#define DW_OP_reg7 0x57 +#define DW_OP_reg8 0x58 +#define DW_OP_reg9 0x59 +#define DW_OP_reg10 0x5a +#define DW_OP_reg11 0x5b +#define DW_OP_reg12 0x5c +#define DW_OP_reg13 0x5d +#define DW_OP_reg14 0x5e +#define DW_OP_reg15 0x5f +#define DW_OP_reg16 0x60 +#define DW_OP_reg17 0x61 +#define DW_OP_reg18 0x62 +#define DW_OP_reg19 0x63 +#define DW_OP_reg20 0x64 +#define DW_OP_reg21 0x65 +#define DW_OP_reg22 0x66 +#define DW_OP_reg23 0x67 +#define DW_OP_reg24 0x68 +#define DW_OP_reg25 0x69 +#define DW_OP_reg26 0x6a +#define DW_OP_reg27 0x6b +#define DW_OP_reg28 0x6c +#define DW_OP_reg29 0x6d +#define DW_OP_reg30 0x6e +#define DW_OP_reg31 0x6f +#define DW_OP_breg0 0x70 +#define DW_OP_breg1 0x71 +#define DW_OP_breg2 0x72 +#define DW_OP_breg3 0x73 +#define DW_OP_breg4 0x74 +#define DW_OP_breg5 0x75 +#define DW_OP_breg6 0x76 +#define DW_OP_breg7 0x77 +#define DW_OP_breg8 0x78 +#define DW_OP_breg9 0x79 +#define DW_OP_breg10 0x7a +#define DW_OP_breg11 0x7b +#define DW_OP_breg12 0x7c +#define DW_OP_breg13 0x7d +#define DW_OP_breg14 0x7e +#define DW_OP_breg15 0x7f +#define DW_OP_breg16 0x80 +#define DW_OP_breg17 0x81 +#define DW_OP_breg18 0x82 +#define DW_OP_breg19 0x83 +#define DW_OP_breg20 0x84 +#define DW_OP_breg21 0x85 +#define DW_OP_breg22 0x86 +#define DW_OP_breg23 0x87 +#define DW_OP_breg24 0x88 +#define DW_OP_breg25 0x89 +#define DW_OP_breg26 0x8a +#define DW_OP_breg27 0x8b +#define DW_OP_breg28 0x8c +#define DW_OP_breg29 0x8d +#define DW_OP_breg30 0x8e +#define DW_OP_breg31 0x8f +#define DW_OP_regx 0x90 +#define DW_OP_fbreg 0x91 +#define DW_OP_bregx 0x92 +#define DW_OP_piece 0x93 +#define DW_OP_deref_size 0x94 +#define DW_OP_xderef_size 0x95 +#define DW_OP_nop 0x96 +#define DW_OP_push_object_address 0x97 /* DWARF3 */ +#define DW_OP_call2 0x98 /* DWARF3 */ +#define DW_OP_call4 0x99 /* DWARF3 */ +#define DW_OP_call_ref 0x9a /* DWARF3 */ +#define DW_OP_form_tls_address 0x9b /* DWARF3f */ +#define DW_OP_call_frame_cfa 0x9c /* DWARF3f */ +#define DW_OP_bit_piece 0x9d /* DWARF3f */ + + + /* GNU extensions. */ +#define DW_OP_GNU_push_tls_address 0xe0 /* GNU */ + +/* Follows extension so dwarfdump prints the most-likely-useful name. */ +#define DW_OP_lo_user 0xe0 + + /* HP extensions. */ +#define DW_OP_HP_unknown 0xe0 /* HP conflict: GNU */ +#define DW_OP_HP_is_value 0xe1 /* HP */ +#define DW_OP_HP_fltconst4 0xe2 /* HP */ +#define DW_OP_HP_fltconst8 0xe3 /* HP */ +#define DW_OP_HP_mod_range 0xe4 /* HP */ +#define DW_OP_HP_unmod_range 0xe5 /* HP */ +#define DW_OP_HP_tls 0xe6 /* HP */ + +#define DW_OP_hi_user 0xff + +#define DW_ATE_address 0x1 +#define DW_ATE_boolean 0x2 +#define DW_ATE_complex_float 0x3 +#define DW_ATE_float 0x4 +#define DW_ATE_signed 0x5 +#define DW_ATE_signed_char 0x6 +#define DW_ATE_unsigned 0x7 +#define DW_ATE_unsigned_char 0x8 +#define DW_ATE_imaginary_float 0x9 /* DWARF3 */ +#define DW_ATE_packed_decimal 0xa /* DWARF3f */ +#define DW_ATE_numeric_string 0xb /* DWARF3f */ +#define DW_ATE_edited 0xc /* DWARF3f */ +#define DW_ATE_signed_fixed 0xd /* DWARF3f */ +#define DW_ATE_unsigned_fixed 0xe /* DWARF3f */ +#define DW_ATE_decimal_float 0xf /* DWARF3f */ + + +/* ALTIUM extensions. x80, x81 */ +#define DW_ATE_ALTIUM_fract 0x80 /* ALTIUM __fract type */ + +/* Follows extension so dwarfdump prints the most-likely-useful name. */ +#define DW_ATE_lo_user 0x80 + +/* Shown here to help dwarfdump build script. */ +#define DW_ATE_ALTIUM_accum 0x81 /* ALTIUM __accum type */ + +/* HP Floating point extensions. */ +#define DW_ATE_HP_float80 0x80 /* (80 bit). HP */ + + +#define DW_ATE_HP_complex_float80 0x81 /* Complex (80 bit). HP */ +#define DW_ATE_HP_float128 0x82 /* (128 bit). HP */ +#define DW_ATE_HP_complex_float128 0x83 /* Complex (128 bit). HP */ +#define DW_ATE_HP_floathpintel 0x84 /* (82 bit IA64). HP */ +#define DW_ATE_HP_imaginary_float80 0x85 /* HP */ +#define DW_ATE_HP_imaginary_float128 0x86 /* HP */ + +/* Sun extensions */ +#define DW_ATE_SUN_interval_float 0x91 +#define DW_ATE_SUN_imaginary_float 0x92 /* Obsolete: See DW_ATE_imaginary_float */ + +#define DW_ATE_hi_user 0xff + + +/* Decimal Sign codes. */ +#define DW_DS_unsigned 0x01 /* DWARF3f */ +#define DW_DS_leading_overpunch 0x02 /* DWARF3f */ +#define DW_DS_trailing_overpunch 0x03 /* DWARF3f */ +#define DW_DS_leading_separate 0x04 /* DWARF3f */ + +#define DW_DS_trailing_separate 0x05 /* DWARF3f */ + +/* Endian code name. */ +#define DW_END_default 0x00 /* DWARF3f */ +#define DW_END_big 0x01 /* DWARF3f */ +#define DW_END_little 0x02 /* DWARF3f */ + +#define DW_END_lo_user 0x40 /* DWARF3f */ +#define DW_END_hi_user 0xff /* DWARF3f */ + +/* for use with DW_TAG_SUN_codeflags + * If DW_TAG_SUN_codeflags is accepted as a dwarf standard, then + * standard dwarf ATCF entries start at 0x01 + */ +#define DW_ATCF_lo_user 0x40 /* SUN */ +#define DW_ATCF_SUN_mop_bitfield 0x41 /* SUN */ +#define DW_ATCF_SUN_mop_spill 0x42 /* SUN */ +#define DW_ATCF_SUN_mop_scopy 0x43 /* SUN */ +#define DW_ATCF_SUN_func_start 0x44 /* SUN */ +#define DW_ATCF_SUN_end_ctors 0x45 /* SUN */ +#define DW_ATCF_SUN_branch_target 0x46 /* SUN */ +#define DW_ATCF_SUN_mop_stack_probe 0x47 /* SUN */ +#define DW_ATCF_SUN_func_epilog 0x48 /* SUN */ +#define DW_ATCF_hi_user 0xff /* SUN */ + +/* Accessibility code name. */ +#define DW_ACCESS_public 0x01 +#define DW_ACCESS_protected 0x02 +#define DW_ACCESS_private 0x03 + +/* Visibility code name. */ +#define DW_VIS_local 0x01 +#define DW_VIS_exported 0x02 +#define DW_VIS_qualified 0x03 + +/* Virtuality code name. */ +#define DW_VIRTUALITY_none 0x00 +#define DW_VIRTUALITY_virtual 0x01 +#define DW_VIRTUALITY_pure_virtual 0x02 + +#define DW_LANG_C89 0x0001 +#define DW_LANG_C 0x0002 +#define DW_LANG_Ada83 0x0003 +#define DW_LANG_C_plus_plus 0x0004 +#define DW_LANG_Cobol74 0x0005 +#define DW_LANG_Cobol85 0x0006 +#define DW_LANG_Fortran77 0x0007 +#define DW_LANG_Fortran90 0x0008 +#define DW_LANG_Pascal83 0x0009 +#define DW_LANG_Modula2 0x000a +#define DW_LANG_Java 0x000b /* DWARF3 */ +#define DW_LANG_C99 0x000c /* DWARF3 */ +#define DW_LANG_Ada95 0x000d /* DWARF3 */ +#define DW_LANG_Fortran95 0x000e /* DWARF3 */ +#define DW_LANG_PLI 0x000f /* DWARF3 */ +#define DW_LANG_ObjC 0x0010 /* DWARF3f */ +#define DW_LANG_ObjC_plus_plus 0x0011 /* DWARF3f */ +#define DW_LANG_UPC 0x0012 /* DWARF3f */ +#define DW_LANG_D 0x0013 /* DWARF3f */ +#define DW_LANG_lo_user 0x8000 +#define DW_LANG_Mips_Assembler 0x8001 /* MIPS */ +#define DW_LANG_Upc 0x8765 /* UPC, use + DW_LANG_UPC instead. */ +/* ALTIUM extension */ +#define DW_LANG_ALTIUM_Assembler 0x9101 /* ALTIUM */ + +/* Sun extensions */ +#define DW_LANG_SUN_Assembler 0x9001 /* SUN */ + +#define DW_LANG_hi_user 0xffff + +/* Identifier case name. */ +#define DW_ID_case_sensitive 0x00 +#define DW_ID_up_case 0x01 +#define DW_ID_down_case 0x02 +#define DW_ID_case_insensitive 0x03 + +/* Calling Convention Name. */ +#define DW_CC_normal 0x01 +#define DW_CC_program 0x02 +#define DW_CC_nocall 0x03 +#define DW_CC_lo_user 0x40 + +/* ALTIUM extensions. */ +/* Function is an interrupt handler, return address on system stack. */ +#define DW_CC_ALTIUM_interrupt 0x65 /* ALTIUM*/ + +/* Near function model, return address on system stack. */ +#define DW_CC_ALTIUM_near_system_stack 0x66 /*ALTIUM */ + +/* Near function model, return address on user stack. */ +#define DW_CC_ALTIUM_near_user_stack 0x67 /* ALTIUM */ + +/* Huge function model, return address on user stack. */ +#define DW_CC_ALTIUM_huge_user_stack 0x68 /* ALTIUM */ + + +#define DW_CC_hi_user 0xff + +/* Inline Code Name. */ +#define DW_INL_not_inlined 0x00 +#define DW_INL_inlined 0x01 +#define DW_INL_declared_not_inlined 0x02 +#define DW_INL_declared_inlined 0x03 + +/* Ordering Name. */ +#define DW_ORD_row_major 0x00 +#define DW_ORD_col_major 0x01 + +/* Discriminant Descriptor Name. */ +#define DW_DSC_label 0x00 +#define DW_DSC_range 0x01 + +/* Line number standard opcode name. */ +#define DW_LNS_copy 0x01 +#define DW_LNS_advance_pc 0x02 +#define DW_LNS_advance_line 0x03 +#define DW_LNS_set_file 0x04 +#define DW_LNS_set_column 0x05 +#define DW_LNS_negate_stmt 0x06 +#define DW_LNS_set_basic_block 0x07 +#define DW_LNS_const_add_pc 0x08 +#define DW_LNS_fixed_advance_pc 0x09 +#define DW_LNS_set_prologue_end 0x0a /* DWARF3 */ +#define DW_LNS_set_epilogue_begin 0x0b /* DWARF3 */ +#define DW_LNS_set_isa 0x0c /* DWARF3 */ + +/* Line number extended opcode name. */ +#define DW_LNE_end_sequence 0x01 +#define DW_LNE_set_address 0x02 +#define DW_LNE_define_file 0x03 + +/* HP extensions. */ +#define DW_LNE_HP_negate_is_UV_update 0x11 /* 17 HP */ +#define DW_LNE_HP_push_context 0x12 /* 18 HP */ +#define DW_LNE_HP_pop_context 0x13 /* 19 HP */ +#define DW_LNE_HP_set_file_line_column 0x14 /* 20 HP */ +#define DW_LNE_HP_set_routine_name 0x15 /* 21 HP */ +#define DW_LNE_HP_set_sequence 0x16 /* 22 HP */ +#define DW_LNE_HP_negate_post_semantics 0x17 /* 23 HP */ +#define DW_LNE_HP_negate_function_exit 0x18 /* 24 HP */ +#define DW_LNE_HP_negate_front_end_logical 0x19 /* 25 HP */ +#define DW_LNE_HP_define_proc 0x20 /* 32 HP */ + +#define DW_LNE_lo_user 0x80 /* DWARF3 */ +#define DW_LNE_hi_user 0xff /* DWARF3 */ + +/* Macro information. */ +#define DW_MACINFO_define 0x01 +#define DW_MACINFO_undef 0x02 +#define DW_MACINFO_start_file 0x03 +#define DW_MACINFO_end_file 0x04 +#define DW_MACINFO_vendor_ext 0xff + +#define DW_CFA_advance_loc 0x40 +#define DW_CFA_offset 0x80 +#define DW_CFA_restore 0xc0 +#define DW_CFA_extended 0 + +#define DW_CFA_nop 0x00 +#define DW_CFA_set_loc 0x01 +#define DW_CFA_advance_loc1 0x02 +#define DW_CFA_advance_loc2 0x03 +#define DW_CFA_advance_loc4 0x04 +#define DW_CFA_offset_extended 0x05 +#define DW_CFA_restore_extended 0x06 +#define DW_CFA_undefined 0x07 +#define DW_CFA_same_value 0x08 +#define DW_CFA_register 0x09 +#define DW_CFA_remember_state 0x0a +#define DW_CFA_restore_state 0x0b +#define DW_CFA_def_cfa 0x0c +#define DW_CFA_def_cfa_register 0x0d +#define DW_CFA_def_cfa_offset 0x0e +#define DW_CFA_def_cfa_expression 0x0f /* DWARF3 */ +#define DW_CFA_expression 0x10 /* DWARF3 */ +#define DW_CFA_cfa_offset_extended_sf 0x11 /* DWARF3 */ +#define DW_CFA_def_cfa_sf 0x12 /* DWARF3 */ +#define DW_CFA_def_cfa_offset_sf 0x13 /* DWARF3 */ +#define DW_CFA_val_offset 0x14 /* DWARF3f */ +#define DW_CFA_val_offset_sf 0x15 /* DWARF3f */ +#define DW_CFA_val_expression 0x16 /* DWARF3f */ + +#define DW_CFA_lo_user 0x1c +#define DW_CFA_low_user 0x1c /* Incorrect spelling, do not use. */ + +/* SGI/MIPS extension. */ +#define DW_CFA_MIPS_advance_loc8 0x1d /* MIPS */ + +/* GNU extensions. */ +#define DW_CFA_GNU_window_save 0x2d /* GNU */ +#define DW_CFA_GNU_args_size 0x2e /* GNU */ +#define DW_CFA_GNU_negative_offset_extended 0x2f /* GNU */ + +#define DW_CFA_high_user 0x3f + +/* GNU exception header encoding. See the Generic + Elf Specification of the Linux Standard Base (LSB). + http://refspecs.freestandards.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html + The upper 4 bits indicate how the value is to be applied. + The lower 4 bits indicate the format of the data. +*/ +#define DW_EH_PE_absptr 0x00 /* GNU */ +#define DW_EH_PE_uleb128 0x01 /* GNU */ +#define DW_EH_PE_udata2 0x02 /* GNU */ +#define DW_EH_PE_udata4 0x03 /* GNU */ +#define DW_EH_PE_udata8 0x04 /* GNU */ +#define DW_EH_PE_sleb128 0x09 /* GNU */ +#define DW_EH_PE_sdata2 0x0A /* GNU */ +#define DW_EH_PE_sdata4 0x0B /* GNU */ +#define DW_EH_PE_sdata8 0x0C /* GNU */ + +#define DW_EH_PE_pcrel 0x10 /* GNU */ +#define DW_EH_PE_textrel 0x20 /* GNU */ +#define DW_EH_PE_datarel 0x30 /* GNU */ +#define DW_EH_PE_funcrel 0x40 /* GNU */ +#define DW_EH_PE_aligned 0x50 /* GNU */ + +#define DW_EH_PE_omit 0xff /* GNU. Means no value present. */ + + +/* Mapping from machine registers and pseudo-regs into the .debug_frame table. + DW_FRAME entries are machine specific. These describe + MIPS/SGI R3000, R4K, R4400. + And (simultaneously) a mapping from hardware register number to + the number used in the table to identify that register. + + The CFA (Canonical Frame Address) described in DWARF is called + the Virtual Frame Pointer on MIPS/SGI machines. + + Rule describes: +*/ +/* Column used for CFA. Assumes reg 0 never appears as + a register in DWARF info. */ +#define DW_FRAME_CFA_COL 0 + +#define DW_FRAME_REG1 1 /* integer reg 1 */ +#define DW_FRAME_REG2 2 /* integer reg 2 */ +#define DW_FRAME_REG3 3 /* integer reg 3 */ +#define DW_FRAME_REG4 4 /* integer reg 4 */ +#define DW_FRAME_REG5 5 /* integer reg 5 */ +#define DW_FRAME_REG6 6 /* integer reg 6 */ +#define DW_FRAME_REG7 7 /* integer reg 7 */ +#define DW_FRAME_REG8 8 /* integer reg 8 */ +#define DW_FRAME_REG9 9 /* integer reg 9 */ +#define DW_FRAME_REG10 10 /* integer reg 10 */ +#define DW_FRAME_REG11 11 /* integer reg 11 */ +#define DW_FRAME_REG12 12 /* integer reg 12 */ +#define DW_FRAME_REG13 13 /* integer reg 13 */ +#define DW_FRAME_REG14 14 /* integer reg 14 */ +#define DW_FRAME_REG15 15 /* integer reg 15 */ +#define DW_FRAME_REG16 16 /* integer reg 16 */ +#define DW_FRAME_REG17 17 /* integer reg 17 */ +#define DW_FRAME_REG18 18 /* integer reg 18 */ +#define DW_FRAME_REG19 19 /* integer reg 19 */ +#define DW_FRAME_REG20 20 /* integer reg 20 */ +#define DW_FRAME_REG21 21 /* integer reg 21 */ +#define DW_FRAME_REG22 22 /* integer reg 22 */ +#define DW_FRAME_REG23 23 /* integer reg 23 */ +#define DW_FRAME_REG24 24 /* integer reg 24 */ +#define DW_FRAME_REG25 25 /* integer reg 25 */ +#define DW_FRAME_REG26 26 /* integer reg 26 */ +#define DW_FRAME_REG27 27 /* integer reg 27 */ +#define DW_FRAME_REG28 28 /* integer reg 28 */ +#define DW_FRAME_REG29 29 /* integer reg 29 */ +#define DW_FRAME_REG30 30 /* integer reg 30 */ +#define DW_FRAME_REG31 31 /* integer reg 31, aka ra */ + + /* MIPS1, 2 have only some of these 64-bit registers. + ** MIPS1 save/restore takes 2 instructions per 64-bit reg, and + ** in that case, the register is considered stored after the second + ** swc1. + */ +#define DW_FRAME_FREG0 32 /* 64-bit floating point reg 0 */ +#define DW_FRAME_FREG1 33 /* 64-bit floating point reg 1 */ +#define DW_FRAME_FREG2 34 /* 64-bit floating point reg 2 */ +#define DW_FRAME_FREG3 35 /* 64-bit floating point reg 3 */ +#define DW_FRAME_FREG4 36 /* 64-bit floating point reg 4 */ +#define DW_FRAME_FREG5 37 /* 64-bit floating point reg 5 */ +#define DW_FRAME_FREG6 38 /* 64-bit floating point reg 6 */ +#define DW_FRAME_FREG7 39 /* 64-bit floating point reg 7 */ +#define DW_FRAME_FREG8 40 /* 64-bit floating point reg 8 */ +#define DW_FRAME_FREG9 41 /* 64-bit floating point reg 9 */ +#define DW_FRAME_FREG10 42 /* 64-bit floating point reg 10 */ +#define DW_FRAME_FREG11 43 /* 64-bit floating point reg 11 */ +#define DW_FRAME_FREG12 44 /* 64-bit floating point reg 12 */ +#define DW_FRAME_FREG13 45 /* 64-bit floating point reg 13 */ +#define DW_FRAME_FREG14 46 /* 64-bit floating point reg 14 */ +#define DW_FRAME_FREG15 47 /* 64-bit floating point reg 15 */ +#define DW_FRAME_FREG16 48 /* 64-bit floating point reg 16 */ +#define DW_FRAME_FREG17 49 /* 64-bit floating point reg 17 */ +#define DW_FRAME_FREG18 50 /* 64-bit floating point reg 18 */ +#define DW_FRAME_FREG19 51 /* 64-bit floating point reg 19 */ +#define DW_FRAME_FREG20 52 /* 64-bit floating point reg 20 */ +#define DW_FRAME_FREG21 53 /* 64-bit floating point reg 21 */ +#define DW_FRAME_FREG22 54 /* 64-bit floating point reg 22 */ +#define DW_FRAME_FREG23 55 /* 64-bit floating point reg 23 */ +#define DW_FRAME_FREG24 56 /* 64-bit floating point reg 24 */ +#define DW_FRAME_FREG25 57 /* 64-bit floating point reg 25 */ +#define DW_FRAME_FREG26 58 /* 64-bit floating point reg 26 */ +#define DW_FRAME_FREG27 59 /* 64-bit floating point reg 27 */ +#define DW_FRAME_FREG28 60 /* 64-bit floating point reg 28 */ +#define DW_FRAME_FREG29 61 /* 64-bit floating point reg 29 */ +#define DW_FRAME_FREG30 62 /* 64-bit floating point reg 30 */ +#define DW_FRAME_FREG31 63 /* 64-bit floating point reg 31 */ + +/* ***IMPORTANT NOTE, TARGET DEPENDENCY **** + The following 4 #defines are dependent on + the target cpu(s) that you apply libdwarf to. + Ensure that DW_FRAME_UNDEFINED_VAL and DW_FRAME_SAME_VAL + do not conflict with the range [0-DW_FRAME_STATIC_LINK]. + The value 63 works for MIPS cpus at least up to the R16000. + + For a cpu with more than 63 real registers + DW_FRAME_HIGHEST_NORMAL_REGISTER + must be increased for things to work properly! + Also ensure that DW_FRAME_UNDEFINED_VAL DW_FRAME_SAME_VAL + are not in the range [0-DW_FRAME_STATIC_LINK] + + Having DW_FRAME_HIGHEST_NORMAL_REGISTER be higher than + is strictly needed is safe. + +*/ + +#ifndef DW_FRAME_HIGHEST_NORMAL_REGISTER +#define DW_FRAME_HIGHEST_NORMAL_REGISTER 63 +#endif +/* This is the number of columns in the Frame Table. + This constant should + be kept in sync with DW_REG_TABLE_SIZE defined in libdwarf.h + It must also be large enough to be beyond the highest + compiler-defined-register (meaning DW_FRAME_RA_COL DW_FRAME_STATIC_LINK + in the MIPS/IRIX case */ +#ifndef DW_FRAME_LAST_REG_NUM +#define DW_FRAME_LAST_REG_NUM (DW_FRAME_HIGHEST_NORMAL_REGISTER + 3) +#endif + + +/* Column recording ra (return addrress from a function call). + This is common to many architectures, but as a 'simple register' + is not necessarily adequate for all architectures. + For MIPS/IRIX this register number is actually recorded on disk + in the .debug_frame section. + */ +#define DW_FRAME_RA_COL (DW_FRAME_HIGHEST_NORMAL_REGISTER + 1) + +/* Column recording static link applicable to up-level + addressing, as in IRIX mp code, pascal, etc. + This is common to many architectures but + is not necessarily adequate for all architectures. + For MIPS/IRIX this register number is actually recorded on disk + in the .debug_frame section. +*/ +#define DW_FRAME_STATIC_LINK (DW_FRAME_HIGHEST_NORMAL_REGISTER + 2) + + + +/* + DW_FRAME_UNDEFINED_VAL and DW_FRAME_SAME_VAL are + never on disk, just generated by libdwarf. See libdwarf.h + for their values. +*/ + + + +#define DW_CHILDREN_no 0x00 +#define DW_CHILDREN_yes 0x01 + +#define DW_ADDR_none 0 + +#ifdef __cplusplus +} +#endif +#endif /* __DWARF_H */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf.v2.mm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf.v2.mm Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,7699 @@ +'\"#ident "%W%" +'\" $Source: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/libdwarf/RCS/dwarf.v2.mm,v $ +'\" +'\" $Revision: 1.2 $ +'\" +'\" DESCRIPTION +'\" +'\" Requirements for +'\" +'\" COMPILATION +'\" +'\" pic file.mm | tbl | troff -mm +'\" +'\" local mileage may vary +'\" +'\" AUTHOR +'\" +'\" UNIX International Programming Languages SIG +'\" +'\" COPYRIGHT +'\" +'\" Copyright (c) 1992,1993, UNIX International +'\" +'\" Permission to use, copy, modify, and distribute this documentation for +'\" any purpose and without fee is hereby granted, provided that the above +'\" copyright notice appears in all copies and that both that copyright +'\" notice and this permission notice appear in supporting documentation, +'\" and that the name UNIX International not be used in advertising or +'\" publicity pertaining to distribution of the software without specific, +'\" written prior permission. UNIX International makes no representations +'\" about the suitability of this documentation for any purpose. It is +'\" provided "as is" without express or implied warranty. +'\" +'\" UNIX INTERNATIONAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +'\" DOCUMENTATION, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +'\" FITNESS. IN NO EVENT SHALL UNIX INTERNATIONAL 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 DOCUMENTATION. +'\" +'\" NOTICE: +'\" +'\" UNIX International is making this documentation available as a +'\" reference point for the industry. While UNIX International believes +'\" that this specification is well defined in this first release of the +'\" document, minor changes may be made prior to products meeting this +'\" specification being made available from UNIX System Laboratories or +'\" UNIX International members. +'\" +'\" $Log$ +'\" Revision 1.1 1994/05/18 18:50:42 davea +'\" Initial revision +'\" +'\" +'\" Abbrevs for funny typeset words +.pl-0.25i +.ds aX U\s-2NIX\s+2 +.ds iX \*(aX International +.ds uL \s-2AT&T\ USL\s+2 +'\" +'\" uI should be set to 1 if the publication and copyright page is needed. +.nr uI 1 +'\" +'\" Make the appropriate replacements in this section! +'\" +'\" Set the ND date to the current date. +'\" tT is the formal document title +'\" tP is the name of the Project (if appropriate) +'\" tD is the short document title +'\" tE is the work group name (may be the same as the project name) +.ds tT DWARF Debugging Information Format +.ds tP +'\" Document name (i.e., without project name) +.ds tD DWARF Debugging Information Format +.ds tE Programming Languages SIG +'\" +'\" Define headers and footers macro +'\" +.ds fA Revision: 2.0.0 +'\" +'\" fB null to remove page numbers on cover page +.ds fB +.ds fC July 27, 1993 +.ds fE Industry Review Draft +.ds fF \*(tD +.PH "''''" +.PF "''\*(fE''" +.tr ~ +.SA 1 +.S 10 +.nr Ej 1 +.nr Hs 5 +.nr Hu 1 +.nr Hb 5 +.ds HP +2 +2 +1 +0 +0 +0 +0 +.ds HF 3 3 3 3 3 1 1 +.if n .ds HF 1 1 1 1 1 1 1 1 +'\" +'\" First page, print title and authors +'\" +.S +4 +.DS C + + + + + + +\fB\*(tT + +\s-2\*(tP\s+2\fP + +.DE +.S +.sp 3i +\*(iX +.br +\*(tE +.br +\*(fA (\*(fC) +.SK +.if \n(uI\{ +.DS C +.in -.25i +.B "Published by:" +.R + +\*(iX +Waterview Corporate Center +20 Waterview Boulevard +Parsippany, NJ 07054 + +for further information, contact: +Vice President of Marketing + +Phone: +1 201-263-8400 +Fax: +1 201-263-8401 +.DE +.P +Copyright \(co 1992, 1993 \*(iX, Inc. +.P +Permission to use, copy, modify, and distribute this +documentation for any purpose and without fee is hereby granted, provided +that the above copyright notice appears in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation, and that the name \*(iX not be used in +advertising or publicity pertaining to distribution of the software +without specific, written prior permission. \*(iX makes +no representations about the suitability of this documentation for any +purpose. It is provided "as is" without express or implied warranty. +.P +UNIX INTERNATIONAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS DOCUMENTATION, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +EVENT SHALL UNIX INTERNATIONAL 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 DOCUMENTATION. +.sp 2l +.if \n(uI\{ +NOTICE: +.P +\*(iX is making this documentation available as a +reference point for the industry. +While \*(iX believes that this specification is well +defined in this first release of the document, +minor changes may be made prior to products meeting this specification +being made available from \*(aX System Laboratories or \*(iX members. +.sp 1l \} +Trademarks: +.P +Intel386 is a trademark of Intel Corporation. +.br +\*(aX\(rg is a registered trademark of \*(aX System Laboratories +in the United States and other countries. +.br +.OH "'''\s10\\\\*(tE\s0'" +.EH "'\s10\\\\*(tD\s0'''" +.SK +'\".VM 0 2 +.PF "''\s10\\\\*(fE\s0''" +.OF "'\s10\\\\*(fA'\\\\*(fB'\\\\*(fC\s0'" +.EF "'\s10\\\\*(fA'\\\\*(fB'\\\\*(fC\s0'" +'\" ----------------------------------------------------------------------- +'\". +'\" Reset page numbers +'\" +.nr P 1 +.nr % 1 +'\" +'\" Define headers and footers +'\" +.FH +'\" Turn on the page numbering in the footers +.ds fB Page % +'\" +'\" MACROEND +'\" +.if n .fp 2 R +.if n .fp 3 R +.tr ~ +\fR +.S 11 +.SA 1 +.tr ~ +.OP +.ds | | +.ds ~ ~ +.ds ' ' +.if t .ds Cw \&\f(CW +.if n .ds Cw \fB +.de Cf \" Place every other arg in Cw font, beginning with first +.if \\n(.$=1 \&\*(Cw\\$1\fP +.if \\n(.$=2 \&\*(Cw\\$1\fP\\$2 +.if \\n(.$=3 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP +.if \\n(.$=4 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4 +.if \\n(.$=5 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP +.if \\n(.$=6 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6 +.if \\n(.$=7 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP +.if \\n(.$=8 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8 +.if \\n(.$=9 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8\*(Cw +.. +'\" macros used by index generating tool +.deIX +.ie '\\n(.z'' .tm .Index: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 \\n% +.el \\!.ix \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +.. +.deix +.ie '\\n(.z'' .tm .Index: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 \\n% +.el \\!.ix \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +.. +.ta .5i +.5i +.5i +.5i +.5i +.5i +.5i +.5i +.HU "FOREWORD" +This document specifies the second generation of symbolic debugging +information based on the DWARF format that +has been developed by the \*(iX +Programming Languages Special Interest Group (SIG). +It is being circulated for industry review. +The first version of the DWARF specification was published +by \*(iX in January, 1992. The current version adds significant +new functionality, but its main thrust is to achieve a much +denser encoding of the DWARF information. Because of the new +encoding, DWARF Version 2 is not binary compatible with +DWARF Version 1. +.P +At this point, the SIG believes that this document sufficiently +supports the debugging needs of C, C++, FORTRAN 77, +Fortran90, Modula2 and Pascal, and we have +released it for public comment. We will accept comments on this +document until September 30, 1994. Comments may be directed via email +to the SIG mailing list (plsig@ui.org). If you are unable +to send email, paper mail, FAX, or machine readable copy +on \*(aX, MS-DOS, or Macintosh compatible media can be +sent to \*(iX at the address listed below, +and will be forwarded to the SIG. +.SP +.SP +.SP +.in +20 +UNIX International +.br +Waterview Corporate Center +.br +20 Waterview Boulevard +.br +Parsippany, NJ 07054 +.br +Phone: +1 201-263-8400 +.br +Fax: +1 201-263-8401 +.br +.in -20 +.nr H1 0 +.OP +.H 1 "INTRODUCTION" +\fR +This document defines the format for the information generated by +compilers, assemblers and linkage editors that is necessary for symbolic, +source-level debugging. The debugging information format does not favor the +design of any compiler or debugger. Instead, the goal is to create a method of +communicating an accurate picture of the source program to any debugger in a +form that is economically extensible to different languages while retaining +backward compatibility. +.P +The design of the debugging information format is open-ended, allowing for the +addition of new debugging information to accommodate new languages or +debugger capabilities while remaining compatible with other languages or +different debuggers. +.H 2 "Purpose and Scope" +The debugging information format described in this document is designed to +meet the symbolic, source-level debugging needs of +different languages in a unified fashion by +requiring language independent debugging information whenever possible. +.IX C++ %caa +.IX virtual functions +.IX Fortran +Individual needs, such as C++ virtual functions or Fortran common blocks are +accommodated by creating attributes that are used only for those +languages. The \*(iX \*(tE believes +that this document sufficiently covers the +.IX languages +debugging information needs of C, C++, FORTRAN77, Fortran90, +Modula2 and Pascal. +.IX C %c +.IX Modula2 +.IX Pascal +.IX FORTRAN77 +.IX Fortran90 +.P +This document describes DWARF Version 2, the second generation of debugging +.IX Version 2 +information based on the DWARF format. While DWARF Version 2 provides +new debugging information not available in Version 1, the primary focus +of the changes for Version 2 is the representation of the information, +rather than the information content itself. The basic structure of +the Version 2 format remains as in Version 1: the debugging information +is represented as a series of debugging information entries, each containing +one or more attributes (name/value pairs). +.IX debugging information entries +.IX attributes +The Version 2 representation, however, +is much more compact than the Version 1 representation. +.IX Version 1 +In some cases, this greater density has been achieved at the expense +of additional complexity or greater difficulty in producing and processing +the DWARF information. We believe that the reduction in I/O and in +memory paging should more than make up for any increase in processing time. +.P +Because the representation of information has changed from Version 1 to +Version 2, Version 2 DWARF information is not binary compatible +.IX compatibility +with Version 1 information. To make it easier for consumers to +support both Version 1 and Version 2 DWARF information, the Version +2 information has been moved to a different object file section, +.Cf .debug_info . +.IX \f(CW.debug_info\fP %debugai +.P +The intended audience for this document are the developers of +both producers and consumers of debugging information, typically +language compilers, debuggers and other tools that need to interpret +a binary program in terms of its original source. +.H 2 "Overview" +There are two major pieces to the description of the DWARF format in +this document. The first piece is the informational content +of the debugging entries. The second piece +is the way the debugging information is encoded and +represented in an object file. +.P +The informational content is described in sections two +through six. +Section two describes the overall structure of +the information and attributes that are common to many or all of +the different debugging information entries. +Sections three, four and five describe the specific debugging +information entries and how they communicate the +necessary information about the source program to a debugger. +Section six describes debugging information contained +outside of the debugging information entries, themselves. +The encoding of the DWARF information is +presented in section seven. +.P +Section eight describes some future directions for the DWARF +specification. +.P +In the following sections, text in normal font describes required aspects +of the DWARF format. Text in \fIitalics\fP is explanatory or supplementary +material, and not part of the format definition itself. +.H 2 "Vendor Extensibility" +.IX vendor extensions +This document does not attempt to cover all interesting languages or even +to cover all of the interesting debugging information needs for its primary +target languages (C, C++, FORTRAN77, Fortran90, Modula2, Pascal). +Therefore the document provides +vendors a way to define their own debugging information tags, attributes, +base type encodings, location operations, language names, +calling conventions and call frame instructions +by reserving a portion of the name space and valid values +for these constructs for vendor specific additions. Future versions +of this document will not use names or values reserved for vendor specific +additions. All names and values not reserved for vendor additions, however, +are reserved for future versions of this document. See section 7 for +details. +.H 2 "Changes from Version 1" +The following is a list of the major changes made to the DWARF Debugging +Information Format since Version 1 of the format was published (January +.IX Version 1 +20, 1992). The list is not meant to be exhaustive. +.BL +.LI +Debugging information entries have been moved from the +.Cf .debug +.IX \f(CW.debug\fP %debugaaa +to the +.Cf .debug_info +.IX \f(CW.debug_info\fP %debugai +section of an object file. +.LI +.IX tags +.IX attributes, names +.IX attributes, forms +The tag, attribute names and attribute forms encodings have been moved +out of the debugging information itself to a separate abbreviations table. +.IX abbreviations table +.LI +Explicit sibling pointers have been made optional. Each +.IX debugging information entries, siblings +entry now specifies (through the abbreviations table) whether +or not it has children. +.IX debugging information entries, child entries +.LI +New more compact attribute forms have been added, including a variable +length constant data form. Attribute values may now have any +.IX variable length data +.IX attributes, forms +.IX attributes, values +form within a given class of forms. +.LI +Location descriptions have been replaced by a new, more compact +and more expressive format. +.IX locations, descriptions +There is now a way of expressing multiple locations for an object +whose location changes during its lifetime. +.IX locations, lists +.LI +There is a new format for line number information +that provides information +for code contributed to a compilation unit from an included file. +Line number information is now in the +.IX line number information +.Cf .debug_line +.IX \f(CW.debug_line\fP %debugali +section of an object file. +.LI +The representation of the type of a declaration has been +reworked. +.IX declarations, types of +.LI +A new section provides an encoding for pre-processor macro information. +.IX macro information +.IX pre-processor +.LI +Debugging information entries now provide for the representation +of non-defining declarations of objects, functions or types. +.IX declarations, non-defining +.LI +More complete support for Modula2 and Pascal has been added. +.LI +There is now a way of describing locations for segmented address spaces. +.IX segmented address space +.IX address space, segmented +.LI +A new section provides an encoding for information about call +frame activations. +.IX call frame information +.IX activations +.LI +The representation of enumeration and array types has been +.IX enumerations +.IX arrays +reworked so that DWARF presents only a single way of +representing lists of items. +.LI +Support has been added for C++ templates and exceptions. +.IX C++ %caa +.IX templates +.IX exceptions +.LE +.OP +.H 1 "GENERAL DESCRIPTION" +.H 2 "The Debugging Information Entry" +DWARF uses a series of debugging information entries to define a +.IX debugging information entries +low-level representation of a source program. Each debugging +information entry is described by an identifying tag and +contains a series of attributes. +The tag specifies the class to which an entry +belongs, and the attributes define the specific characteristics +of the entry. +.P +.nr aX \n(Fg+1 +The set of required tag names is listed in Figure \n(aX. +.IX tags +The debugging information entries they identify are described in sections three, four and five. +.P +The debugging information entries in DWARF Version 2 are intended +to exist in the +.Cf .debug_info +section of an object file. +.IX \f(CW.debug_info\fP %debugai +.DF +.TS +center box; +lf(CW) lf(CW) +. +DW_TAG_access_declaration DW_TAG_array_type +DW_TAG_base_type DW_TAG_catch_block +DW_TAG_class_type DW_TAG_common_block +DW_TAG_common_inclusion DW_TAG_compile_unit +DW_TAG_const_type DW_TAG_constant +DW_TAG_entry_point DW_TAG_enumeration_type +DW_TAG_enumerator DW_TAG_file_type +DW_TAG_formal_parameter DW_TAG_friend +DW_TAG_imported_declaration DW_TAG_inheritance +DW_TAG_inlined_subroutine DW_TAG_label +DW_TAG_lexical_block DW_TAG_member +DW_TAG_module DW_TAG_namelist +DW_TAG_namelist_item DW_TAG_packed_type +DW_TAG_pointer_type DW_TAG_ptr_to_member_type +DW_TAG_reference_type DW_TAG_set_type +DW_TAG_string_type DW_TAG_structure_type +DW_TAG_subprogram DW_TAG_subrange_type +DW_TAG_subroutine_type DW_TAG_template_type_param +DW_TAG_template_value_param DW_TAG_thrown_type +DW_TAG_try_block DW_TAG_typedef +DW_TAG_union_type DW_TAG_unspecified_parameters +DW_TAG_variable DW_TAG_variant +DW_TAG_variant_part DW_TAG_volatile_type +DW_TAG_with_stmt +.TE +.FG "Tag names" +.DE +.H 2 "Attribute Types" +Each attribute value is characterized by an attribute name. +.IX attributes +.IX attributes, names +The set of attribute names is +.nr aX \n(Fg+1 +listed in Figure \n(aX. +.DF +.TS +center box; +lf(CW) lf(CW) +. +DW_AT_abstract_origin DW_AT_accessibility +DW_AT_address_class DW_AT_artificial +DW_AT_base_types DW_AT_bit_offset +DW_AT_bit_size DW_AT_byte_size +DW_AT_calling_convention DW_AT_common_reference +DW_AT_comp_dir DW_AT_const_value +DW_AT_containing_type DW_AT_count +DW_AT_data_member_location DW_AT_decl_column +DW_AT_decl_file DW_AT_decl_line +DW_AT_declaration DW_AT_default_value +DW_AT_discr DW_AT_discr_list +DW_AT_discr_value DW_AT_encoding +DW_AT_external DW_AT_frame_base +DW_AT_friend DW_AT_high_pc +DW_AT_identifier_case DW_AT_import +DW_AT_inline DW_AT_is_optional +DW_AT_language DW_AT_location +DW_AT_low_pc DW_AT_lower_bound +DW_AT_macro_info DW_AT_name +DW_AT_namelist_item DW_AT_ordering +DW_AT_priority DW_AT_producer +DW_AT_prototyped DW_AT_return_addr +DW_AT_segment DW_AT_sibling +DW_AT_specification DW_AT_start_scope +DW_AT_static_link DW_AT_stmt_list +DW_AT_stride_size DW_AT_string_length +DW_AT_type DW_AT_upper_bound +DW_AT_use_location DW_AT_variable_parameter +DW_AT_virtuality DW_AT_visibility +DW_AT_vtable_elem_location +.TE +.FG "Attribute names" +.DE +.P +The permissible values for an attribute belong to one or more classes +.IX attributes, values +.IX attributes, forms +of attribute value forms. Each form class may be represented in one or more +ways. For instance, some attribute values consist of a single piece +of constant data. ``Constant data'' is the class of attribute value +that those attributes may have. There are several representations +of constant data, however (one, two, four, eight bytes and variable +length data). The particular representation for any given instance +of an attribute is encoded along with the attribute name as part +of the information that guides the interpretation of a debugging +information entry. Attribute value forms may belong +to one of the following classes. +.VL 18 +.LI address +.IX attributes, addresses +Refers to some location in the address space of the described program. +.LI block +.IX attributes, blocks +An arbitrary number of uninterpreted bytes of data. +.LI constant +.IX attributes, constants +One, two, four or eight bytes of uninterpreted data, or data encoded +in the variable length format known as LEB128 (see section 7.6). +.IX variable length data +.IX LEB128 +.LI flag +.IX attributes, flags +A small constant that indicates the presence or absence of an attribute. +.LI reference +.IX attributes, references +Refers to some member of the set of debugging information entries that describe +the program. There are two types of reference. The first is an +offset relative to the beginning of the compilation unit in +which the reference occurs and must refer to an entry within +that same compilation unit. The second type of reference +is the address of any debugging information entry within +the same executable or shared object; it may refer to an entry +in a different compilation unit from the unit containing the +reference. +.LI string +.IX attributes, strings +A null-terminated sequence of zero or more (non-null) bytes. +Data in this form are generally printable strings. Strings +may be represented directly in the debugging information entry +or as an offset in a separate string table. +.LE +.P +There are no limitations on the ordering of attributes within a debugging +.IX attributes, ordering +information entry, but to prevent ambiguity, +no more than one attribute with a given name may appear in any debugging +information entry. +.H 2 "Relationship of Debugging Information Entries" +.I +A variety of needs can be met by permitting a single debugging +information entry to ``own'' an arbitrary number of other debugging +entries and by permitting the same debugging information entry to be +one of many owned by another debugging information entry. +This makes it possible to describe, for example, +the static block structure within +a source file, show the members of a structure, union, or class, and associate +declarations with source files or source files with shared objects. +.P +.R +The ownership relation +of debugging information entries is achieved naturally +.IX debugging information entries +because the debugging information is represented as a tree. +The nodes of the tree are the debugging information entries +themselves. The child entries of any node are exactly those +.IX debugging information entries, child entries +debugging information entries owned by that node.\*F +.FS +While the ownership relation of the debugging information +entries is represented as a tree, other relations among +the entries exist, for example, a pointer from an entry +representing a variable to another entry representing +the type of that variable. If all such relations are +taken into account, the debugging entries form a graph, +not a tree. +.FE +.P +The tree itself is represented by flattening it in prefix +order. Each debugging information entry +is defined either to have child entries or not to have child entries +(see section 7.5.3). +If an entry is defined not to have children, the next physically +succeeding entry is the sibling of the prior entry. If an entry +.IX debugging information entries, siblings +is defined to have children, the next physically succeeding entry +is the first child of the prior entry. Additional children of the parent +entry are represented as siblings of the first child. A chain +of sibling entries is terminated by a null entry. +.IX debugging information entries, null entries +.P +In cases where a producer of debugging information +feels that it will be important for consumers of that information +to quickly scan chains of sibling entries, ignoring the children +of individual siblings, that producer may attach an +.Cf AT_sibling +attribute to any debugging information entry. The value of +this attribute is a reference to the sibling entry of the +entry to which the attribute is attached. +.H 2 "Location Descriptions" +.I +The debugging information must provide consumers a way to find the location +of program variables, determine the bounds of dynamic arrays and strings +and possibly to find the base address of a subroutine's stack frame or +the return address of a subroutine. Furthermore, to meet the needs +of recent computer architectures and optimization techniques, the debugging +information must be able to describe the location of an object +whose location changes over the object's lifetime. +.P +.R +Information about the location of program objects is provided by +location descriptions. Location +.IX locations, descriptions +descriptions can be either of two forms: +.AL +.LI +\fILocation expressions\fP which are a language independent representation of +addressing rules +.IX locations, expressions +of arbitrary complexity built from a few basic +building blocks, or \fIoperations\fP. They are sufficient for describing +the location of any object as long as its lifetime is either static +or the same as the lexical block that owns it, and it does not move throughout +its lifetime. +.LI +\fILocation lists\fP which are used to describe objects that +.IX locations, lists +have a limited lifetime or change their location throughout their +lifetime. Location lists are more completely described below. +.LE +.P +The two forms are distinguished in a context sensitive manner. As the value +of an attribute, a location expression is +encoded as a block and a location list is encoded as a constant offset into +a location list table. +.P +.I +Note: The Version 1 concept of "location descriptions" was replaced in Version 2 +with this new abstraction because it is denser and more descriptive. +.IX Version 1 +.IX Version 2 +.R +.H 3 "Location Expressions" +A location expression consists of zero or more location operations. +.IX locations, expressions +An expression with zero operations +is used to denote an object that is +present in the source code but not present in the object code +(perhaps because of optimization). +.IX optimized code +The location operations fall into two categories, register names and +addressing operations. Register names always appear alone and indicate +that the referred object is contained inside a particular +register. Addressing operations are memory address computation +rules. All location operations are encoded as a stream of opcodes that +are each followed by zero or more literal operands. The number of operands +is determined by the opcode. +.H 3 "Register Name Operators" +.IX locations, register name operators +The following operations can be used to name a register. +.P +.I +Note that the +register number represents a DWARF specific mapping of numbers onto +the actual registers of a given architecture. +The mapping should be chosen to gain optimal density and +should be shared by all users of a given architecture. +The \*(tE recommends +that this mapping be defined by the ABI\*F +.IX ABI +.FS +\fISystem V Application Binary Interface\fP, consisting of the generic +interface and processor supplements for each target architecture. +.FE +authoring committee for each +architecture. +.R +.AL +.LI +.Cf DW_OP_reg0 , " DW_OP_reg1" ", ..., " DW_OP_reg31 +.br +The +\f(CWDW_OP_reg\fP\fIn\fP +operations encode the names of up to 32 registers, numbered from +0 through 31, inclusive. The object addressed is in register \fIn\fP. +.LI +.Cf DW_OP_regx +.br +The +.Cf DW_OP_regx +operation has a single unsigned LEB128 literal operand that encodes the +name of a register. +.LE +.H 3 "Addressing Operations" +.IX locations, stack +Each addressing operation represents a postfix operation on a simple stack +machine. Each element of the stack is the size of an +address on the target machine. +The value on the top of the stack after +``executing'' the location expression is taken to be the result (the address +of the object, or the value of the array bound, or the length of a +dynamic string). In the case of locations used for structure members, +.IX members, locations +the computation assumes that the base address of the containing structure +has been pushed on the stack before evaluation of the addressing operation. +.R +.H 4 "Literal Encodings" +.IX locations, literal encodings +The following operations all push a value onto the addressing stack. +.AL +.LI +.Cf DW_OP_lit0 , " DW_OP_lit1" ", ..., " DW_OP_lit31 +.br +The +\f(CWDW_OP_lit\fP\fIn\fP operations encode the unsigned +literal values from 0 through 31, inclusive. +.LI +.Cf DW_OP_addr +.br +The +.Cf DW_OP_addr +operation has a single operand that encodes a +machine address and whose size is the size of an address on the +target machine. +.LI +.Cf DW_OP_const1u +.br +The single operand of the +.Cf DW_OP_const1u +operation provides a 1-byte unsigned integer constant. +.LI +.Cf DW_OP_const1s +.br +The single operand of the +.Cf DW_OP_const1s +operation provides a +1-byte signed integer constant. +.LI +.Cf DW_OP_const2u +.br +The single operand of the +.Cf DW_OP_const2u +operation provides a +2-byte unsigned integer constant. +.LI +.Cf DW_OP_const2s +.br +The single operand of the +.Cf DW_OP_const2s +operation provides a +2-byte signed integer constant. +.LI +.Cf DW_OP_const4u +.br +The single operand of the +.Cf DW_OP_const4u +operation provides a +4-byte unsigned integer constant. +.LI +.Cf DW_OP_const4s +.br +The single operand of the +.Cf DW_OP_const4s +operation provides a +4-byte signed integer constant. +.LI +.Cf DW_OP_const8u +.br +The single operand of the +.Cf DW_OP_const8u +operation provides an +8-byte unsigned integer constant. +.LI +.Cf DW_OP_const8s +.br +The single operand of the +.Cf DW_OP_const8s +operation provides an +8-byte signed integer constant. +.LI +.Cf DW_OP_constu +.br +The single operand of the +.Cf DW_OP_constu +operation provides an +unsigned LEB128 integer constant. +.LI +.Cf DW_OP_consts +.br +The single operand of the +.Cf DW_OP_consts +operation provides a +signed LEB128 integer constant. +.LE +.H 4 "Register Based Addressing" +.IX locations, register based addressing +The following operations push a value onto the stack that +is the result of adding the contents of a register with +a given signed offset. +.AL +.LI +.Cf DW_OP_fbreg +.br +The +\f(CWDW_OP_fbreg\fP +operation provides a signed LEB128 offset from the address specified +by the location descriptor in the +.Cf DW_AT_frame_base +attribute of the current +.IX subroutines, frame base +function. \fI(This is typically a "stack pointer" register +plus or minus some +offset. On more sophisticated systems it might be a location list that +adjusts the offset according to changes in the stack pointer as +the PC changes.)\fP +.LI +.Cf DW_OP_breg0 , " DW_OP_breg1" ", ..., " DW_OP_breg31 +.br +The single operand of the +\f(CWDW_OP_breg\fP\fIn\fP +operations provides a signed LEB128 offset from the specified register. +.LI +.Cf DW_OP_bregx +.br +The +.Cf DW_OP_bregx +operation has two operands: a signed LEB128 offset from the specified register +which is defined with an unsigned LEB128 number. +.LE +.H 4 "Stack Operations" +.IX locations, stack +The following operations +manipulate the ``location stack.'' +Location operations that index the location stack assume that +the top of the stack (most recently added entry) has index 0. +.AL +.LI +.Cf DW_OP_dup +.br +The +.Cf DW_OP_dup +operation duplicates the value at the top of the location stack. +.LI +.Cf DW_OP_drop +.br +The +.Cf DW_OP_drop +operation pops the value at the top of the stack. +.LI +.Cf DW_OP_pick +.br +The single operand of the +.Cf DW_OP_pick +operation provides a 1-byte index. The stack entry with the specified index +(0 through 255, inclusive) is pushed on the stack. +.LI +.Cf DW_OP_over +.br +The +.Cf DW_OP_over +operation duplicates the entry currently second in the stack +at the top of the stack. This is equivalent to an +.Cf DW_OP_pick +operation, with index 1. +.LI +.Cf DW_OP_swap +.br +The +.Cf DW_OP_swap +operation swaps the top two stack entries. The entry at +the top of the stack becomes the second stack entry, and +the second entry becomes the top of the stack. +.LI +.Cf DW_OP_rot +.br +The +.Cf DW_OP_rot +operation rotates the first three stack entries. The entry at +the top of the stack becomes the third stack entry, the second entry +becomes the top of the stack, and the third entry becomes the second +entry. +.LI +.Cf DW_OP_deref +.br +The +.Cf DW_OP_deref +operation pops the top stack entry and treats it as an address. +The value retrieved from that address is pushed. The size of the +data retrieved from the dereferenced address is the size of an address +on the target machine. +.LI +.Cf DW_OP_deref_size +.br +The +.Cf DW_OP_deref_size +operation behaves like the +.Cf DW_OP_deref +operation: it +pops the top stack entry and treats it as an address. +The value retrieved from that address is pushed. +In the +.Cf DW_OP_deref_size +operation, however, +the size in bytes of the +data retrieved from the dereferenced address is specified by the +single operand. This operand is a 1-byte unsigned integral constant +whose value may not be larger than the size of an address on +the target machine. The data retrieved is zero extended to the size +of an address on the target machine before being pushed on +the expression stack. +.LI +.Cf DW_OP_xderef +.br +The +.Cf DW_OP_xderef +.IX address space, multiple +operation provides an extended dereference mechanism. The entry at the +top of the stack is treated as an address. The second stack entry +is treated as an ``address space identifier'' for those architectures +that support multiple address spaces. The top two stack elements +are popped, a data item is retrieved through an implementation-defined +address calculation and pushed as the new stack top. The size of the +data retrieved from the dereferenced address is the size of an address +on the target machine. +.LI +.Cf DW_OP_xderef_size +.br +The +.Cf DW_OP_xderef_size +operation behaves like the +.Cf DW_OP_xderef +operation: the entry at the +top of the stack is treated as an address. The second stack entry +is treated as an ``address space identifier'' for those architectures +that support multiple address spaces. The top two stack elements +are popped, a data item is retrieved through an implementation-defined +address calculation and pushed as the new stack top. +In the +.Cf DW_OP_xderef_size +operation, however, +the size in bytes of the +data retrieved from the dereferenced address is specified by the +single operand. This operand is a 1-byte unsigned integral constant +whose value may not be larger than the size of an address on +the target machine. The data retrieved is zero extended to the size +of an address on the target machine before being pushed on +the expression stack. +.LE +.H 4 "Arithmetic and Logical Operations" +.IX locations, arithmetic operations +.IX locations, logical operations +The following provide arithmetic and logical operations. +The arithmetic operations perform ``addressing arithmetic,'' +that is, unsigned arithmetic that wraps on an address-sized +boundary. The operations do not cause an exception on overflow. +.AL +.LI +.Cf DW_OP_abs +.br +The +.Cf DW_OP_abs +operation pops the top stack entry and pushes its absolute value. +.LI +.Cf DW_OP_and +.br +The +.Cf DW_OP_and +operation pops the top two stack values, performs a bitwise \fIand\fP +operation on the two, and pushes the result. +.LI +.Cf DW_OP_div +.br +The +.Cf DW_OP_div +operation pops the top two stack values, divides the former second entry +by the former top of the stack +using signed division, +and pushes the result. +.LI +.Cf DW_OP_minus +.br +The +.Cf DW_OP_minus +operation pops the top two stack values, subtracts the former top of the stack +from the former second entry, and pushes the result. +.LI +.Cf DW_OP_mod +.br +The +.Cf DW_OP_mod +operation pops the top two stack values and pushes the result of the +calculation: former second stack entry modulo the former top of the +stack. +.LI +.Cf DW_OP_mul +.br +The +.Cf DW_OP_mul +operation pops the top two stack entries, multiplies them together, +and pushes the result. +.LI +.Cf DW_OP_neg +.br +The +.Cf DW_OP_neg +operation pops the top stack entry, and pushes its negation. +.LI +.Cf DW_OP_not +.br +The +.Cf DW_OP_not +operation pops the top stack entry, and pushes its bitwise complement. +.LI +.Cf DW_OP_or +.br +The +.Cf DW_OP_or +operation pops the top two stack entries, performs a bitwise \fIor\fP +operation on the two, and pushes the result. +.LI +.Cf DW_OP_plus +.br +The +.Cf DW_OP_plus +operation pops the top two stack entries, adds them together, +and pushes the result. +.LI +.Cf DW_OP_plus_uconst +.br +The +.Cf DW_OP_plus_uconst +operation pops the top stack entry, adds it to the unsigned LEB128 +constant operand and pushes the result. +.I +This operation is supplied specifically to be able to encode more field +offsets in two bytes than can be done with "\f(CWDW_OP_lit\fP\fIn\fP\f(CW DW_OP_add\fP". +.R +.LI +.Cf DW_OP_shl +.br +The +.Cf DW_OP_shl +operation pops the top two stack entries, shifts the former second +entry left by the number of bits specified by the former top of +the stack, and pushes the result. +.LI +.Cf DW_OP_shr +.br +The +.Cf DW_OP_shr +operation pops the top two stack entries, shifts the former second +entry right (logically) by the number of bits specified by the former top of +the stack, and pushes the result. +.LI +.Cf DW_OP_shra +.br +The +.Cf DW_OP_shra +operation pops the top two stack entries, shifts the former second +entry right (arithmetically) by the number of bits specified by the former top of +the stack, and pushes the result. +.LI +.Cf DW_OP_xor +.br +The +.Cf DW_OP_xor +operation pops the top two stack entries, performs the logical +\fIexclusive-or\fP operation on the two, and pushes the result. +.LE +.H 4 "Control Flow Operations" +.IX locations, control flow operations +The following operations provide simple control of the flow of a location +expression. +.AL +.LI +Relational operators +.br +The six relational operators each pops the top two stack values, +compares the former top of the stack with the former second entry, +and pushes the constant value 1 onto the stack if the result of the +operation is true or the constant value 0 if the result of the operation +is false. The comparisons are done as signed operations. The six +operators are +.Cf DW_OP_le +(less than or equal to), +.Cf DW_OP_ge +(greater than or equal to), +.Cf DW_OP_eq +(equal to), +.Cf DW_OP_lt +(less than), +.Cf DW_OP_gt +(greater than) and +.Cf DW_OP_ne +(not equal to). +.LI +.Cf DW_OP_skip +.br +.Cf DW_OP_skip +is an unconditional branch. Its +single operand is a 2-byte signed integer constant. +The 2-byte constant is the number of bytes of the location +expression to skip from the current operation, beginning after the +2-byte constant. +.LI +.Cf DW_OP_bra +.br +.Cf DW_OP_bra +is a conditional branch. Its +single operand is a 2-byte signed integer constant. +This operation pops the top of stack. If the value +popped is not the constant 0, the 2-byte constant operand is the number +of bytes of the location +expression to skip from the current operation, beginning after the +2-byte constant. +.LE +.H 4 "Special Operations" +.IX locations, special operations +There are two special operations currently defined: +.AL +.LI +.Cf DW_OP_piece +.br +.I +Many compilers store a single variable in sets of registers, or store +a variable partially in memory and partially in registers. +.Cf DW_OP_piece +provides a way of describing how large a part of a variable +a particular addressing expression refers to. +.R +.P +.Cf DW_OP_piece +takes a single argument which is an unsigned LEB128 number. The number +describes the size in bytes of the piece of the object referenced +by the addressing expression whose result is at the top of +the stack. +.LI +.Cf DW_OP_nop +.br +The +.Cf DW_OP_nop +operation is a place holder. It has no effect on the location stack or +any of its values. +.LE +.H 3 "Sample Stack Operations" +.IX locations, examples +.I +The stack operations defined in section 2.4.3.3 are fairly +.IX locations, stack +conventional, but the following examples illustrate their behavior +graphically. +.R +.DS +.TS +box expand center tab(;); +l s l l s +lf(CW) lf(CW) lf(CW) lf(CW) lf(CW) +. +Before;Operation;After; +_ +0;17;DW_OP_dup;0;17 +1;29;;1;17 +2;1000;;2;29 +;;;3;1000 +_ +0;17;DW_OP_drop;0;29 +1;29;;1;1000 +2;1000;;;; +_ +0;17;DW_OP_pick 2;0;1000 +1;29;;1;17 +2;1000;;2;29 +;;;3;1000 +_ +0;17;DW_OP_over;0;29 +1;29;;1;17 +2;1000;;2;29 +;;;3;1000 +_ +0;17;DW_OP_swap;0;29 +1;29;;1;17 +2;1000;;2;1000 +_ +0;17;DW_OP_rot;0;29 +1;29;;1;1000 +2;1000;;2;17 +.TE +.DE +.H 3 "Example Location Expressions" +.I +.IX locations, examples +The addressing expression represented by a location expression, +if evaluated, generates the +runtime address of the value of a symbol except where the +.Cf DW_OP_reg n, +or +.Cf DW_OP_regx +operations are used. +.P +Here are some examples of how location operations are used to form location +expressions: +.R +.DS +\f(CWDW_OP_reg3\fI + The value is in register 3. + +\f(CWDW_OP_regx 54\fI + The value is in register 54. + +\f(CWDW_OP_addr 0x80d0045c\fI + The value of a static variable is + at machine address 0x80d0045c. + +\f(CWDW_OP_breg11 44\fI + Add 44 to the value in + register 11 to get the address of an + automatic variable instance. + +\f(CWDW_OP_fbreg -50\fI + Given an \f(CWDW_AT_frame_base\fI value of + "\f(CWOPBREG31 64\fI," this example + computes the address of a local variable + that is -50 bytes from a logical frame + pointer that is computed by adding + 64 to the current stack pointer (register 31). + +\f(CWDW_OP_bregx 54 32 DW_OP_deref\fI + A call-by-reference parameter + whose address is in the + word 32 bytes from where register + 54 points. + +\f(CWDW_OP_plus_uconst 4\fI + A structure member is four bytes + from the start of the structure + instance. The base address is + assumed to be already on the stack. + +\f(CWDW_OP_reg3 DW_OP_piece 4 DW_OP_reg10 DW_OP_piece 2\fI + A variable whose first four bytes reside + in register 3 and whose next two bytes + reside in register 10.\fR +.DE +.H 3 "Location Lists" +.IX locations, lists +Location lists are used in place of location expressions whenever +the object whose location is being described can change location +during its lifetime. Location lists are contained in a separate +object file section called +.Cf .debug_loc. +.IX \f(CW.debug_loc\fP %debugalo +A location list is indicated by a location +attribute whose value is represented as a +constant offset from the beginning of the +.Cf .debug_loc +section to the first byte of the list for the object in question. +.P +Each entry in a location list consists of: +.AL +.LI +A beginning address. This address is relative to the base address +of the compilation unit referencing this location list. It marks +the beginning of the address range over which the location is valid. +.LI +An ending address, again relative to the base address +of the compilation unit referencing this location list. It marks +the first address past the end of the address range over +which the location is valid. +.LI +A location expression describing the location of the object over the +range specified by the beginning and end addresses. +.LE +.P +Address ranges may overlap. When they do, they describe a situation +in which an object exists simultaneously in more than one place. +If all of the address ranges +in a given location list do not collectively cover the entire +range over which the object in question is defined, it is assumed +that the object is not available for the portion of the range that is not +covered. +.IX optimized code +.P +The end of any given location list is marked by a 0 for the beginning +address and a 0 for the end address; no location description is present. +A location list containing +only such a 0 entry describes an object that exists in the source +code but not in the executable program. +.H 2 "Types of Declarations" +.IX declarations, types of +Any debugging information entry describing a declaration that +has a type has a +.Cf DW_AT_type +attribute, whose value is a reference to another debugging +information entry. The entry referenced may describe +.IX base types +.IX types, base +a base type, that is, a type that is not defined in terms +.IX user-defined types +.IX types, user-defined +of other data types, or it may describe a user-defined type, +such as an array, structure or enumeration. Alternatively, +the entry referenced may describe a type modifier: constant, +packed, pointer, reference or volatile, which in turn will reference +another entry describing a type or type modifier (using a +.IX type modifiers +.IX types, modifiers +.IX types, packed +.IX types, constant +.IX types, pointer +.IX types, reference +.IX types, volatile +.Cf DW_AT_type +attribute of its own). See section 5 for descriptions of +the entries describing base types, user-defined types and +type modifiers. +.H 2 "Accessibility of Declarations" +.I +.IX accessibility +.IX declarations, accessibility +Some languages, notably C++ and Ada, have the concept of +.IX C++ %caa +the accessibility of an object or of some other program entity. +The accessibility specifies which classes of other program objects +are permitted access to the object in question. +.R +.P +The accessibility of a declaration is represented by a +.Cf DW_AT_accessibility +attribute, whose value is a constant drawn from the set of codes +.nr aX \n(Fg+1 +listed in Figure \n(aX. +.DF +.TS +box center; +lf(CW) +. +DW_ACCESS_public +DW_ACCESS_private +DW_ACCESS_protected +.TE +.FG "Accessibility codes" +.DE +.H 2 "Visibility of Declarations" +.I +.IX Modula2 +.IX visibility +.IX declarations, visibility +Modula2 has the concept of the visibility of a declaration. +The visibility specifies which declarations are to be visible outside +of the module in which they are declared. +.R +.P +The visibility of a declaration is represented by a +.Cf DW_AT_visibility +attribute, whose value is a constant drawn from the set of codes +.nr aX \n(Fg+1 +listed in Figure \n(aX. +.DF +.TS +box center; +lf(CW) +. +DW_VIS_local +DW_VIS_exported +DW_VIS_qualified +.TE +.FG "Visibility codes" +.DE +.H 2 "Virtuality of Declarations" +.I +.IX C++ %caa +.IX virtuality +.IX virtual functions +C++ provides for virtual and pure virtual structure or class +member functions and for virtual base classes. +.P +.R +The virtuality of a declaration is represented by a +.Cf DW_AT_virtuality +attribute, whose value is a constant drawn from the set of codes +.nr aX \n(Fg+1 +listed in Figure \n(aX. +.DF +.TS +box center; +lf(CW) +. +DW_VIRTUALITY_none +DW_VIRTUALITY_virtual +DW_VIRTUALITY_pure_virtual +.TE +.FG "Virtuality codes" +.DE +.H 2 "Artificial Entries" +.I +.IX artificial entries +A compiler may wish to generate debugging information entries +for objects or types that were not actually declared +in the source of the application. An example is a formal parameter +entry to represent the hidden +.Cf this +parameter that most C++ implementations pass as the first argument +to non-static member functions. +.R +.P +Any debugging information entry representing the declaration of an +object or type artificially generated by a compiler and +not explicitly declared by the source program may have a +.Cf DW_AT_artificial +attribute. The value of this attribute is a flag. +.H 2 "Target-Specific Addressing Information" +.I +.IX segmented address space +.IX address space, segmented +In some systems, addresses are specified as offsets within a given +segment rather than as locations within a single flat address space. +.R +.P +Any debugging information entry that contains a description of the +location of an object or subroutine may have a +.Cf DW_AT_segment +attribute, whose value is a location description. The description +evaluates to the segment value of the item being described. If +the entry containing the +.Cf DW_AT_segment +attribute has a +.Cf DW_AT_low_pc +or +.Cf DW_AT_high_pc +attribute, or a location description that evaluates to an address, +.IX locations, descriptions +.IX addresses, offset portion +then those values represent the offset portion of the address +within the segment specified by +.Cf DW_AT_segment . +.P +If an entry has no +.Cf DW_AT_segment +attribute, it inherits the segment value from its parent entry. +If none of the entries in the chain of parents for this entry +back to its containing compilation unit entry have +.Cf DW_AT_segment +attributes, then the entry is assumed to exist within a flat +address space. Similarly, if the entry has a +.IX flat address space +.IX address space, flat +.Cf DW_AT_segment +attribute containing an empty location description, that entry +is assumed to exist within a flat address space. +.P +.I +Some systems support different classes of addresses. The address +class may affect the way a pointer is dereferenced or the way +a subroutine is called. +.P +.R +Any debugging information entry representing a pointer or reference +type or a subroutine or subroutine type may have a +.IX types, pointer +.IX types, reference +.IX subroutines +.IX subroutines, types +.Cf DW_AT_address_class +.IX addresses, class +attribute, whose value is a constant. The set of permissible +values is specific to each target architecture. The value +.Cf DW_ADDR_none , +however, is common to all encodings, and means that no address class +has been specified. +.P +.I +For example, the Intel386\(tm processor might use the following +values: +.R +.DF +.TS +box center; +l l l +lf(CW) lf(CW) l +. +Name Value Meaning +_ +DW_ADDR_none 0 no class specified +DW_ADDR_near16 1 16-bit offset, no segment +DW_ADDR_far16 2 16-bit offset, 16-bit segment +DW_ADDR_huge16 3 16-bit offset, 16-bit segment +DW_ADDR_near32 4 32-bit offset, no segment +DW_ADDR_far32 5 32-bit offset, 16-bit segment +.TE +.FG "Example address class codes" +.DE +.H 2 "Non-Defining Declarations" +.IX declarations, non-defining +.IX declarations, defining +A debugging information entry representing a program object or type +typically represents the defining declaration of that object or type. In +certain contexts, however, a debugger might need information about a +declaration of a subroutine, object or type that is not also a +definition to evaluate an expression correctly. +.P +.I +As an example, consider the following fragment of C code: +.DS +\f(CWvoid myfunc() +{ + int x; + { + extern float x; + g(x); + } +}\fP +.DE +.P +ANSI-C scoping rules require that the value of the variable \f(CWx\fP +passed to the function \f(CWg\fP is the value of the global variable +\f(CWx\fP rather than of the local version. +.R +.P +Debugging information entries that represent non-defining declarations +of a program object or type have a +.Cf DW_AT_declaration +attribute, whose value is a flag. +.H 2 "Declaration Coordinates" +.I +It is sometimes useful in a debugger to be able to associate a declaration +with its occurrence in the program source. +.P +.R +.IX declarations, coordinates +Any debugging information entry representing the declaration of +an object, module, subprogram or type may have +.Cf DW_AT_decl_file , +.Cf DW_AT_decl_line +and +.Cf DW_AT_decl_column +attributes, each of whose value is a constant. +.P +The value of the +.Cf DW_AT_decl_file +attribute corresponds +to a file number from the statement information table for the compilation +.IX line number information +unit containing this debugging information entry and represents the +source file in which the declaration appeared (see section 6.2). +.IX source, files +The value 0 indicates that no source file has been specified. +.P +The value of the +.Cf DW_AT_decl_line +attribute represents the source line number at which the first +.IX source, lines +character of the identifier of the declared object appears. +The value 0 indicates that no source line has been specified. +.P +The value of the +.Cf DW_AT_decl_column +attribute represents the source column number at which the first +.IX source, columns +character of the identifier of the declared object appears. +The value 0 indicates that no column has been specified. +.H 2 "Identifier Names" +.IX identifiers, names +Any debugging information entry representing a program entity that +has been given a name may have a +.Cf DW_AT_name +attribute, whose value is a string representing the name as it appears +in the source program. A debugging information entry containing +no name attribute, or containing a name attribute whose value consists +of a name containing a single null byte, +represents a program entity for which no name was given in the source. +.I +.P +Note that since the names of program objects +described by DWARF are the names as they appear in the source program, +implementations of language translators that use some form of mangled +name (as do many implementations of C++) should use the unmangled +.IX C++ %caa +form of the name in the DWARF +.Cf DW_AT_name +attribute, including the keyword +.Cf operator , +if present. Sequences of multiple whitespace characters may be compressed. +.R +.OP +.H 1 "PROGRAM SCOPE ENTRIES" +This section describes debugging information entries that relate +to different levels of program scope: compilation unit, module, +subprogram, and so on. These entries may be thought of as +bounded by ranges of text addresses within the program. +.H 2 "Compilation Unit Entries" +An object file may be derived from one or more compilation units. Each +such compilation unit will be described by a debugging information +entry with the tag \f(CWDW_TAG_compile_unit\fP. +.I +.P +A compilation unit typically represents the text and data contributed +.IX compilation units +to an executable by a single relocatable object file. It may +be derived from several source files, including pre-processed ``include +files.'' +.R +.P +The compilation unit entry may have the following attributes: +.AL +.LI +A +.Cf DW_AT_low_pc +attribute whose value is the +relocated address of the first machine instruction generated for that +compilation unit. +.LI +A +.Cf DW_AT_high_pc +attribute whose value is the +relocated address of the first location +past the last machine instruction generated for that compilation unit. +.P +.I +The address may be beyond the last valid instruction in the executable, +of course, for this and other similar attributes. +.R +.P +The presence of low and high pc attributes in a compilation unit entry +imply that the code generated for that compilation unit is +contiguous and exists totally within the boundaries specified +by those two attributes. If that is not the case, no low +and high pc attributes should be produced. +.IX address space, contiguous +.LI +A +.Cf DW_AT_name +attribute whose value is a +null-terminated string containing the full or relative path name of +the primary source file from which the compilation unit was derived. +.IX source, files +.LI +A +.Cf DW_AT_language +attribute whose constant value is +.IX languages +a code indicating the source language of the compilation unit. +.nr aX \n(Fg+1 +The set of language names and their meanings are +given in Figure \n(aX. +.DF +.TS +box center; +lf(CW) lf(R) +. +DW_LANG_C Non-ANSI C, such as K&R +DW_LANG_C89 ISO/ANSI C +DW_LANG_C_plus_plus C++ +DW_LANG_Fortran77 FORTRAN77 +DW_LANG_Fortran90 Fortran90 +DW_LANG_Modula2 Modula2 +DW_LANG_Pascal83 ISO/ANSI Pascal +.TE +.FG "Language names" +.DE +.LI +A +.Cf DW_AT_stmt_list +attribute whose value is a reference to +line number information for this compilation unit. +.IX line number information +.P +This information is placed in a separate object file section from the debugging +information entries themselves. The value of the statement list attribute +is the offset in the \f(CW.debug_line\fP section of the first byte of the +line number information for this compilation unit. See section 6.2. +.LI +A +.Cf DW_AT_macro_info +attribute whose value is a reference to the macro information for this +compilation unit. +.IX macro information +.P +This information is placed in a separate object file section from the debugging +information entries themselves. The value of the macro information attribute +is the offset in the \f(CW.debug_macinfo\fP section of the first byte of the +macro information for this compilation unit. See section 6.3. +.LI +A +.Cf DW_AT_comp_dir +attribute whose value is a null-terminated string containing +the current working directory of the compilation command that +produced this compilation unit in whatever form makes sense +for the host system. +.P +.I +The suggested form for the value of the \f(CWDW_AT_comp_dir\fP +attribute on \*(aX systems is ``hostname\f(CW:\fPpathname''. If no +hostname is available, the suggested form is ``\f(CW:\fPpathname''. +.R +.LI +A +.Cf DW_AT_producer +attribute whose value is a null-terminated string containing information +about the compiler that produced the compilation unit. The +actual contents of the string will be specific to each producer, +but should begin with the name of the compiler vendor or some +other identifying character sequence that should avoid +confusion with other producer values. +.LI +A +.Cf DW_AT_identifier_case +.IX identifiers, case +attribute whose constant value is a code describing the treatment of +identifiers within this compilation unit. The set of identifier case +.nr aX \n(Fg+1 +codes is given in Figure \n(aX. +.DF +.TS +box center; +lf(CW) +. +DW_ID_case_sensitive +DW_ID_up_case +DW_ID_down_case +DW_ID_case_insensitive +.TE +.FG "Identifier case codes" +.DE +.P +.Cf DW_ID_case_sensitive +is the default for all compilation units that do not have this attribute. +It indicates that names given as the values of +.Cf DW_AT_name +attributes in debugging information entries for the compilation unit +reflect the names as they appear in the source program. +The debugger should be sensitive to the case of identifier names +when doing identifier lookups. +.P +.Cf DW_ID_up_case +means that the producer of the debugging information for this compilation +unit converted all source names to upper case. The values of the +name attributes may not reflect the names as they appear in the source +program. The debugger should convert all names to upper case +when doing lookups. +.P +.Cf DW_ID_down_case +means that the producer of the debugging information for this compilation +unit converted all source names to lower case. The values of the +name attributes may not reflect the names as they appear in the source +program. The debugger should convert all names to lower case when +doing lookups. +.P +.Cf DW_ID_case_insensitive +means that the values of the name attributes reflect the names +as they appear in the source program but that a case insensitive +lookup should be used to access those names. +.LI +A +.Cf DW_AT_base_types +.IX base types +.IX types, base +attribute whose value is a reference. This attribute points to +a debugging information entry representing another compilation +unit. It may be used to specify the compilation unit containing +the base type entries used by entries in the current compilation +unit (see section 5.1). +.P +.I +This attribute provides a consumer a way to find the definition +of base types for a compilation unit that does not itself +contain such definitions. This allows a consumer, for example, +to interpret a type conversion to a base type correctly. +.R +.LE +.R +.P +A compilation unit entry +owns debugging information entries that represent the declarations made in +the corresponding compilation unit. +.H 2 "Module Entries" +.I +Several languages have the concept of a ``module.'' +.IX modules +.P +.R +A module is +represented by a debugging information entry with the tag +.Cf DW_TAG_module . +Module entries may own other debugging information entries describing +program entities whose declaration scopes end at the end of the module +itself. +.P +If the module has a name, the module entry has a +.Cf DW_AT_name +attribute whose +value is a null-terminated string containing the module name as it appears +in the source program. +.P +If the module contains initialization code, the module entry +has a +.Cf DW_AT_low_pc +attribute whose value is the +relocated address of the first machine instruction generated for that +initialization code. It also has a +.Cf DW_AT_high_pc +attribute whose value is +the relocated address of the first location past the last machine +instruction generated for the initialization code. +.P +If the module has been assigned a priority, it may have a +.Cf DW_AT_priority +attribute. The value of this attribute is a reference to another +.IX modules, priority +debugging information entry describing a variable with a constant +value. The value of this variable is the actual constant +value of the module's priority, represented as it would be on the +target architecture. +.P +.I +.IX Modula2 +.IX modules, definition +A Modula2 definition module may be represented by a module entry +containing a +.Cf DW_AT_declaration +attribute. +.R +.H 2 "Subroutine and Entry Point Entries" +.IX subroutines +.IX entry points +The following tags exist to describe debugging information +entries for subroutines and entry points: +.VL 30 +.LI \f(CWDW_TAG_subprogram\fP +A global or file static subroutine or function. +.LI \f(CWDW_TAG_inlined_subroutine\fP +A particular inlined instance of a subroutine or function. +.LI \f(CWDW_TAG_entry_point\fP +A Fortran entry point. +.LE +.H 3 "General Subroutine and Entry Point Information" +The subroutine or entry point entry has a +.Cf DW_AT_name +attribute +whose value is a null-terminated string containing the subroutine or entry +point name as it appears in the source program. +.P +If the name of the subroutine described by an entry with the tag +.Cf DW_TAG_subprogram +is visible outside of its containing compilation unit, that +entry has a +.Cf DW_AT_external +attribute, whose value is a flag. +.IX declarations, external +.I +.P +.IX members, functions +.IX subroutines, members +Additional attributes for functions that are members of a class or +structure are described in section 5.5.5. +.P +A common debugger feature is to allow the debugger user to call a +subroutine within the subject program. In certain cases, however, +the generated code for a subroutine will not obey the standard calling +conventions for the target architecture and will therefore not +.IX calling conventions +be safe to call from within a debugger. +.R +.P +A subroutine entry may contain a +.Cf DW_AT_calling_convention +attribute, whose value is a constant. If this attribute is not +present, or its value is the constant +.Cf DW_CC_normal , +then the subroutine may be safely called by obeying the ``standard'' +calling conventions of the target architecture. If the value of +the calling convention attribute is the constant +.Cf DW_CC_nocall , +the subroutine does not obey standard calling conventions, and it +may not be safe for the debugger to call this subroutine. +.P +If the semantics of the language of the compilation unit +containing the subroutine entry distinguishes between ordinary subroutines +.IX main programs +and subroutines that can serve as the ``main program,'' that is, subroutines +that cannot be called directly following the ordinary calling conventions, +then the debugging information entry for such a subroutine may have a +calling convention attribute whose value is the constant +.Cf DW_CC_program . +.P +.I +The +.Cf DW_CC_program +value is intended to support Fortran main programs. +It is not intended as a way of finding the entry address for the program. +.R +.H 3 "Subroutine and Entry Point Return Types" +.IX subroutines, return types +.IX entry points, return types +If the subroutine or entry point is a function that returns a value, then +its debugging information entry has a +.Cf DW_AT_type +attribute to denote the type returned by that function. +.P +.I +Debugging information entries for C +.Cf void +.IX C %c +functions should not have an attribute for the return type. +.P +In ANSI-C there is a difference between the types of functions +declared using function prototype style declarations and those +declared using non-prototype declarations. +.IX subroutines, prototypes +.P +.R +A subroutine entry +declared with a function prototype style declaration may have a +.Cf DW_AT_prototyped +attribute, whose value is a flag. +.H 3 "Subroutine and Entry Point Locations" +.IX subroutines, locations +.IX entry points, locations +A subroutine entry has a +.Cf DW_AT_low_pc +attribute whose value is the relocated address of the first machine instruction +generated for the subroutine. +It also has a +.Cf DW_AT_high_pc +attribute whose value is the relocated address of the +first location past the last machine instruction generated +for the subroutine. +.P +.I +Note that for the low and high pc attributes to have meaning, DWARF +makes the assumption that the code for a single subroutine is allocated +in a single contiguous block of memory. +.IX address space, contiguous +.R +.P +An entry point has a +.Cf DW_AT_low_pc +attribute whose value is the relocated address of the first machine instruction +generated for the entry point. +.P +Subroutines and entry points may also have +.Cf DW_AT_segment +and +.Cf DW_AT_address_class +.IX segmented address space +.IX address space, segmented +.IX addresses, class +attributes, as appropriate, to specify which segments the code +for the subroutine resides in and the addressing mode to be used +in calling that subroutine. +.P +A subroutine entry representing a subroutine declaration +that is not also a definition does not have low and high pc attributes. +.IX declarations, non-defining +.H 3 "Declarations Owned by Subroutines and Entry Points" +.IX subroutines, declarations owned by +.IX entry points, declarations owned by +The declarations enclosed by a subroutine or entry point +are represented by debugging information entries that are +owned by the subroutine or entry point entry. +Entries representing the formal parameters of the subroutine or +entry point appear in +the same order as the corresponding declarations in the source program. +.IX attributes, ordering +.IX parameters, formal +.P +.I +There is no ordering requirement on entries for declarations that are +children of subroutine or entry point entries but that do not represent +formal parameters. The formal parameter entries may be interspersed +with other entries used by formal parameter entries, such as type entries. +.R +.P +The unspecified parameters of a variable parameter list +.IX parameters, unspecified +are represented by a debugging information entry with the tag +.Cf DW_TAG_unspecified_parameters . +.P +The entry for a subroutine or entry point that includes a Fortran +.IX Fortran +.IX common blocks +common block has a child entry with the tag +.Cf DW_TAG_common_inclusion . +The common inclusion entry has a +.Cf DW_AT_common_reference +attribute whose value is a reference to the debugging entry for +the common block being included (see section 4.2). +.H 3 "Low-Level Information" +A subroutine or entry point entry may have a +.Cf DW_AT_return_addr +.IX subroutines, return addresses +attribute, whose value is a location description. +The location calculated is the place where the return address for +the subroutine or entry point is stored. +.P +A subroutine or entry point entry may also have a +.Cf DW_AT_frame_base +.IX subroutines, frame base +attribute, whose value is a location description that +computes the ``frame base'' for the subroutine or entry point. +.P +.I +The frame base for a procedure is typically an address fixed +relative to the first unit of storage allocated for the procedure's +stack frame. The +.Cf DW_AT_frame_base +attribute can be used in several ways: +.AL +.LI +In procedures that need location lists to locate local variables, the +.Cf DW_AT_frame_base +can hold the needed location list, while all variables' +location descriptions can be simpler location expressions involving the frame +base. +.LI +It can be used as a key in resolving "up-level" addressing with nested +routines. (See +.Cf DW_AT_static_link , +below) +.LE +.P +Some languages support nested subroutines. In such languages, it is possible +.IX subroutines, nested +to reference the local variables of an outer subroutine from within +an inner subroutine. The +.Cf DW_AT_static_link +and +.Cf DW_AT_frame_base +attributes allow debuggers to support this same kind of referencing. +.R +.P +If a subroutine or entry point is nested, it may have a +.Cf DW_AT_static_link +attribute, whose value is a location description that +computes the frame base of the relevant instance of the subroutine +that immediately encloses the subroutine or entry point. +.P +In the context of supporting nested subroutines, the +.Cf DW_AT_frame_base +attribute value should obey the following constraints: +.AL +.LI +It should compute a value that does not change during the life of the procedure, +and +.LI +The computed value should be unique among instances of the same subroutine. +(For typical +.Cf DW_AT_frame_base +use, this means that a recursive +subroutine's stack frame must have non-zero size.) +.LE +.P +.I +If a debugger is attempting to resolve an up-level reference to a variable, it +uses the nesting structure of DWARF to determine which subroutine is the lexical +parent and the +.Cf DW_AT_static_link +value to identify the appropriate active frame +of the parent. It can then attempt to find the reference within the context +of the parent. +.R +.H 3 "Types Thrown by Exceptions" +.I +In C++ a subroutine may declare a set of types for which +.IX C++ %caa +.IX exceptions +that subroutine may generate or ``throw'' an exception. +.P +.R +If a subroutine explicitly declares that it may throw an +exception for one or more types, each such type is +represented by a debugging information entry with the tag +.Cf DW_TAG_thrown_type . +Each such entry is a child of the entry representing the +subroutine that may throw this type. All thrown type entries +should follow all entries representing the formal parameters +of the subroutine and precede all entries representing the +local variables or lexical blocks contained in the subroutine. +Each thrown type entry contains a +.Cf DW_AT_type +attribute, whose value is a reference to an entry describing +the type of the exception that may be thrown. +.H 3 "Function Template Instantiations" +.I +.IX C++ %caa +.IX templates +In C++ a function template is a generic +definition of a function that +is instantiated differently when called with values +of different types. DWARF does not represent the generic +template definition, but does represent each instantiation. +.R +.P +A template instantiation is represented by a debugging information +entry with the tag +.Cf DW_TAG_subprogram . +With three exceptions, +such an entry will contain the same attributes and have the same +types of child entries as would an entry for a subroutine +defined explicitly +using the instantiation types. The exceptions are: +.AL +.LI +Each formal parameterized type declaration appearing in the +template definition is represented by a debugging information entry +with the tag +.Cf DW_TAG_template_type_parameter . +Each such entry has a +.Cf DW_AT_name +attribute, whose value is a null-terminated +string containing the name of the formal type parameter as it +appears in the source program. The template type parameter +entry also has a +.Cf DW_AT_type +attribute describing the actual type by +which the formal is replaced for this instantiation. +All template type parameter entries should appear before +the entries describing the instantiated formal parameters +to the function. +.LI +.IX compilation units +If the compiler has generated a special compilation unit +to hold the template instantiation and that compilation unit +has a different name +from the compilation unit containing the template definition, +the name attribute for the debugging entry representing +that compilation unit should be empty or omitted. +.LI +.IX declarations, coordinates +If the subprogram entry representing the template instantiation +or any of its child entries +contain declaration coordinate attributes, those attributes +should refer to the source for the template definition, not +to any source generated artificially by the compiler for this +instantiation. +.LE +.H 3 "Inline Subroutines" +.IX subroutines, inline +A declaration or a definition of an inlinable subroutine +is represented by a debugging information entry with the tag +.Cf DW_TAG_subprogram . +The entry for a subroutine that is explicitly declared +to be available for inline expansion or that was expanded inline +implicitly by the compiler has a +.Cf DW_AT_inline +attribute whose value is a constant. The set of values +for the +.Cf DW_AT_inline +.nr aX \n(Fg+1 +attribute is given in Figure \n(aX. +.DF +.TS +box center; +l l +lf(CW) l +. +Name Meaning +_ +DW_INL_not_inlined Not declared inline nor inlined by the compiler +DW_INL_inlined Not declared inline but inlined by the compiler +DW_INL_declared_not_inlined Declared inline but not inlined by the compiler +DW_INL_declared_inlined Declared inline and inlined by the compiler +.TE +.FG "Inline codes" +.DE +.H 4 "Abstract Instances" +For the remainder of this discussion, +any debugging information entry that is owned (either directly or +indirectly) by a debugging information entry that contains the +.Cf DW_AT_inline +attribute will be referred to as an ``abstract instance entry.'' +Any subroutine entry that contains a +.Cf DW_AT_inline +attribute will be known as an ``abstract instance root.'' +Any set of abstract instance entries that are all children (either directly +or indirectly) of some abstract instance root, together with the root itself, +will be known as an ``abstract instance tree.'' +.P +A debugging information entry that is a member of an abstract instance +tree should not contain a +.Cf DW_AT_high_pc , +.Cf DW_AT_low_pc , +.Cf DW_AT_location , +.Cf DW_AT_return_addr , +.Cf DW_AT_start_scope , +or +.Cf DW_AT_segment +attribute. +.P +.I +It would not make sense to put these attributes +into abstract instance entries since +such entries do not represent actual (concrete) instances and thus +do not actually exist at run-time. +.P +.R +The rules for the relative location of entries belonging to abstract instance +trees are exactly +the same as for other similar types of entries that are not abstract. +Specifically, the rule that requires that an entry representing a +declaration be a direct child of the entry representing the scope of +the declaration applies equally to both abstract and +non-abstract entries. Also, the ordering rules for formal parameter entries, +member entries, and so on, all apply regardless of whether or not a given entry +is abstract. +.H 4 "Concrete Inlined Instances" +.IX subroutines, inlined +Each inline expansion of an inlinable subroutine is represented +by a debugging information entry with the tag +.Cf DW_TAG_inlined_subroutine . +Each such entry should be a direct child of the entry that represents the +scope within which the inlining occurs. +.P +Each inlined subroutine entry contains a +.Cf DW_AT_low_pc +attribute, representing the address of the first +instruction associated with the given inline +expansion. Each inlined subroutine entry also contains a +.Cf DW_AT_high_pc +attribute, representing the +address of the first location past the last instruction associated with +the inline expansion. +.P +For the remainder of this discussion, +any debugging information entry that is owned (either directly or indirectly) +by a debugging information entry with the tag +.Cf DW_TAG_inlined_subroutine +will be referred to as a ``concrete inlined instance entry.'' +Any entry that has the tag +.Cf DW_TAG_inlined_subroutine +will be known as +a ``concrete inlined instance root.'' +Any set of concrete inlined instance entries that are all children (either +directly or indirectly) of some concrete inlined instance root, together +with the root itself, will be known as a ``concrete inlined instance +tree.'' +.P +Each concrete inlined instance tree is uniquely associated with one (and +only one) abstract instance tree. +.P +.I +Note, however, that the reverse is not true. Any given abstract instance +tree may be associated with several different concrete inlined instance +trees, or may even be associated with zero concrete inlined instance +trees. +.P +.R +Also, each separate entry within a given concrete inlined instance tree is +uniquely associated with one particular entry in the associated abstract +instance tree. In other words, there is a one-to-one mapping from entries +in a given concrete inlined instance tree to the entries in the associated +abstract instance tree. +.P +.I +Note, however, that the reverse is not true. A given abstract instance +tree that is associated with a given concrete inlined instance tree +may (and quite probably will) contain more entries than the associated +concrete inlined instance tree (see below). +.R +.P +Concrete inlined instance entries do not have most of the attributes (except +for +.Cf DW_AT_low_pc , +.Cf DW_AT_high_pc , +.Cf DW_AT_location , +.Cf DW_AT_return_addr , +.Cf DW_AT_start_scope +and +.Cf DW_AT_segment ) +that such entries +would otherwise normally have. In place of these omitted attributes, +each concrete inlined instance entry has a +.Cf DW_AT_abstract_origin +attribute that +may be used to obtain the missing information (indirectly) from +the associated abstract instance entry. The value of the abstract +origin attribute is a reference to the associated abstract instance entry. +.P +For each pair of entries that are associated via a +.Cf DW_AT_abstract_origin +attribute, both members of the pair will have the same tag. So, for +example, an entry with the tag +.Cf DW_TAG_local_variable +can only be associated +with another entry that also has the tag +.Cf DW_TAG_local_variable. +The only exception to this rule is that the root of a concrete +instance tree (which must always have the tag +.Cf DW_TAG_inlined_subroutine ) +can only be associated with the root of its associated abstract +instance tree (which must have the tag +.Cf DW_TAG_subprogram ). +.P +In general, the structure and content of any given concrete +instance tree will be directly analogous to the structure and content +of its associated abstract instance tree. +There are two exceptions to this general rule however. +.AL +.LI +.IX anonymous types +No entries representing anonymous types are ever made a part +of any concrete instance inlined tree. +.LI +.IX members +No entries representing members of structure, union or class +types are ever made a part of any concrete inlined instance tree. +.LE +.P +.I +Entries that represent members and anonymous types are omitted from concrete +inlined instance trees because they would simply be redundant duplicates of +the corresponding entries in the associated abstract instance trees. If +any entry within a concrete inlined instance tree needs to refer to an +anonymous type that was declared within the scope of the +relevant inline function, the reference should simply refer to the abstract +instance entry for the given anonymous type. +.R +.P +.IX declarations, coordinates +If an entry within a concrete inlined instance tree contains +attributes describing the declaration coordinates of +that entry, +then those attributes should refer to the file, line and column +of the original declaration of the subroutine, not to the +point at which it was inlined. +.H 4 "Out-of-Line Instances of Inline Subroutines" +.IX subroutines, out-of-line +Under some conditions, compilers may need to generate concrete executable +instances of inline subroutines other than at points where those subroutines +are actually called. For the remainder of this discussion, +such concrete instances of inline subroutines will +be referred to as ``concrete out-of-line instances.'' +.P +.I +In C++, for example, taking the address of a function declared to be inline +can necessitate the generation of a concrete out-of-line +instance of the given function. +.P +.R +The DWARF representation of a concrete out-of-line instance of an inline +subroutine is essentially the same as for a concrete inlined instance of +that subroutine (as described in the preceding section). The representation +of such a concrete out-of-line instance makes use of +.Cf DW_AT_abstract_origin +attributes in exactly the same way as they are used for a concrete inlined +instance (that is, as references to corresponding entries +within the associated +abstract instance tree) and, as for concrete instance trees, the +entries for anonymous types and for all members are omitted. +.P +The differences between the DWARF representation of a concrete out-of-line +instance of a given subroutine and the representation of a concrete inlined +instance of that same subroutine are as follows: +.AL +.LI +The root entry for a concrete out-of-line instance of a given +inline subroutine has the same tag as does its associated +(abstract) inline subroutine entry (that is, it does not have the +tag +.Cf DW_TAG_inlined_subroutine ). +.LI +The root entry for a concrete out-of-line instance tree is +always directly owned by the same parent entry that +also owns the root entry of the associated abstract instance. +.LE +.H 2 "Lexical Block Entries" +.I +.IX lexical blocks +A lexical block is a bracketed sequence of source statements that may +contain any number of declarations. In some languages (C and C++) +blocks can be nested within other blocks to any depth. +.P +.R +A lexical block is represented by a debugging information entry +with the tag +.Cf DW_TAG_lexical_block . +.P +The lexical block entry has a +.Cf DW_AT_low_pc +attribute whose value is the +relocated address of the first machine instruction generated for the lexical +block. +The lexical block entry also has a +.Cf DW_AT_high_pc +attribute whose value is the +relocated address of the first location +past the last machine instruction generated for the lexical block. +.P +If a name has been given to the lexical block in the source program, +then the corresponding lexical block entry has a +.Cf DW_AT_name +attribute +whose value is a null-terminated string containing the name of the +lexical block as it appears in the source program. +.P +.I +This is not the +same as a C or C++ label (see below). +.R +.P +The lexical block entry owns debugging information entries that +describe the declarations within that lexical block. +There is one such debugging information entry for each local declaration +of an identifier or inner lexical block. +.H 2 "Label Entries" +.I +.IX labels +A label is a way of identifying a source statement. A labeled statement +is usually the target of one or more ``go to'' statements. +.P +.R +A label is represented by a debugging information entry +with the tag +.Cf DW_TAG_label . +The entry for a label should be owned by +the debugging information entry representing the scope within which the name +of the label could be legally referenced within the source program. +.P +The label entry has a +.Cf DW_AT_low_pc +attribute whose value is the +relocated address of the first machine instruction generated for the +statement identified by the label in the source program. +The label entry also has a +.Cf DW_AT_name +attribute +whose value is a null-terminated string containing the name of the +label as it appears in the source program. +.H 2 "With Statement Entries" +.I +.IX with statements +.IX Pascal +.IX Modula2 +Both Pascal and Modula support the concept of a ``with'' statement. +The with statement specifies a sequence of executable statements +within which the fields of a record variable may be referenced, unqualified +by the name of the record variable. +.P +.R +A with statement is represented by a debugging information entry with +the tag +.Cf DW_TAG_with_stmt . +A with statement entry has a +.Cf DW_AT_low_pc +attribute whose value is the relocated +address of the first machine instruction generated for the body of +the with statement. A with statement entry also has a +.Cf DW_AT_high_pc +attribute whose value is the relocated +address of the first location after the last machine instruction generated for the body of +the statement. +.P +The with statement entry has a +.Cf DW_AT_type +attribute, denoting +the type of record whose fields may be referenced without full qualification +within the body of the statement. It also has a +.Cf DW_AT_location +attribute, describing how to find the base address +of the record object referenced within the body of the with statement. +.H 2 "Try and Catch Block Entries" +.I +.IX C++ %caa +.IX exceptions +.IX try blocks +.IX catch blocks +In C++ a lexical block may be designated as a ``catch block.'' +A catch block is an exception handler that handles exceptions +thrown by an immediately preceding ``try block.'' A catch block +designates the type of the exception that it can handle. +.R +.P +A try block is represented by a debugging information entry +with the tag +.Cf DW_TAG_try_block . +A catch block is represented by a debugging information entry +with the tag +.Cf DW_TAG_catch_block . +Both try and catch block entries contain a +.Cf DW_AT_low_pc +attribute whose value is the +relocated address of the first machine instruction generated for that +block. These entries also contain a +.Cf DW_AT_high_pc +attribute whose value is the +relocated address of the first location +past the last machine instruction generated for that block. +.P +Catch block entries have at least one child entry, +an entry representing the type of exception accepted +by that catch block. This child entry will have one of the tags +.Cf DW_TAG_formal_parameter +or +.Cf DW_TAG_unspecified_parameters , +.IX parameters, formal +.IX parameters, unspecified +and will have the same form as other parameter entries. +.P +The first sibling of each try block entry will be a catch block +entry. +.OP +.H 1 "DATA OBJECT AND OBJECT LIST ENTRIES" +This section presents the debugging information entries that +describe individual data objects: variables, parameters and +constants, and lists of those objects that may be grouped +in a single declaration, such as a common block. +.H 2 "Data Object Entries" +.IX variables +.IX parameters, formal +.IX constants +Program variables, formal parameters and constants are represented +by debugging information entries with the tags +.Cf DW_TAG_variable , +.Cf DW_TAG_formal_parameter +and +.Cf DW_TAG_constant , +respectively. +.P +.I +The tag +.Cf DW_TAG_constant +is used for languages that distinguish between variables +that may have constant value and true named constants. +.R +.P +The debugging information entry for a program variable, formal +parameter or constant may have the following attributes: +.AL +.LI +A +.Cf DW_AT_name +attribute whose value is a null-terminated +string containing the data object name as it appears in the source program. +.P +.IX anonymous unions +.IX unions, anonymous +.IX C++ %caa +If a variable entry describes a C++ anonymous union, the name +attribute is omitted or consists of a single zero byte. +.LI +If the name of a variable is visible outside of its enclosing +compilation unit, the variable entry has a +.Cf DW_AT_external +.IX declarations, external +attribute, whose value is a flag. +.I +.P +.IX members, static data +The definitions of C++ static data members +of structures or classes are represented by variable entries flagged +as external. +.IX C %c +.IX C++ %caa +Both file static and local variables in C and C++ are represented +by non-external variable entries. +.R +.LI +A +.Cf DW_AT_location +attribute, whose value describes the location of a variable or parameter +at run-time. +.P +.IX declarations, non-defining +A data object entry representing a non-defining declaration of the object +will not have a location attribute, and will have the +.Cf DW_AT_declaration +attribute. +.P +In a variable entry representing the definition of the variable +(that is, with no +.Cf DW_AT_declaration +attribute) +if no location attribute is present, or if +the location attribute is present but describes +a null entry (as described in section 2.4), the variable +is assumed to exist in the source code but not in the executable +program (but see number 9, below). +.IX optimized code +.P +The location of a variable may be further specified with a +.Cf DW_AT_segment +attribute, if appropriate. +.IX segmented address space +.IX address space, segmented +.LI +A +.Cf DW_AT_type +attribute describing the type of the variable, constant or formal +parameter. +.LI +.IX members, static data +.IX declarations, defining +If the variable entry represents the defining declaration for a C++ static +data member of a structure, class or union, the entry has a +.Cf DW_AT_specification +attribute, whose value is a reference to the debugging information +entry representing the declaration of this data member. The +referenced entry will be a child of some class, structure or +union type entry. +.IX classes +.IX structures +.IX unions +.P +Variable entries containing the +.Cf DW_AT_specification +attribute do not need to duplicate information provided by the +declaration entry referenced by the specification attribute. +In particular, such variable entries do not need to contain +attributes for the name or type of the data member whose +definition they represent. +.LI +.I +Some languages distinguish between parameters whose value in the +calling function can be modified by the callee (variable parameters), +and parameters whose value in the calling function cannot be modified +by the callee (constant parameters). +.P +.R +If a formal parameter entry represents a parameter whose value +in the calling function may be modified by the callee, that entry +may have a +.Cf DW_AT_variable_parameter +attribute, whose value is a flag. The absence of this attribute +implies that the parameter's value in the calling function cannot +be modified by the callee. +.IX parameters, variable +.LI +.I +Fortran90 has the concept of an optional parameter. +.IX Fortran90 +.P +.R +.IX parameters, optional +If a parameter entry represents an optional parameter, it has a +.Cf DW_AT_is_optional +attribute, whose value is a flag. +.LI +.IX parameters, default value +A formal parameter entry describing a formal parameter that has a default +value may have a +.Cf DW_AT_default_value +attribute. The value of this attribute is a reference to the +debugging information entry for a variable or subroutine. The +default value of the parameter is the value of the variable (which +may be constant) or the value returned by the subroutine. If the +value of the +.Cf DW_AT_default_value +attribute is 0, it means that no default value has been specified. +.LI +.IX constants +An entry describing a variable whose value is constant +and not represented by an object in the address space of the program, +or an entry describing a named constant, +does not have a location attribute. Such entries have a +.Cf DW_AT_const_value +attribute, whose value may be a string or any of the constant +data or data block forms, as appropriate for the representation +of the variable's value. The value of this attribute is the actual +constant value of the variable, represented as it would be +on the target architecture. +.LI +.IX scope +.IX declarations, scope +If the scope of an object begins sometime after the low pc value +for the scope most closely enclosing the object, the +object entry may have a +.Cf DW_AT_start_scope +attribute. The value of this attribute is the offset in bytes of the beginning +of the scope for the object from the low pc value of the debugging +information entry that defines its scope. +.P +.I +The scope of a variable may begin somewhere in the middle of a lexical +block in a language that allows executable code in a +block before a variable declaration, or where one declaration +containing initialization code may change the scope of a subsequent +declaration. For example, in the following C code: +.DS +\f(CWfloat x = 99.99; + +int myfunc() +{ + float f = x; + float x = 88.99; + + return 0; +}\fP +.DE +.P +ANSI-C scoping rules require that the value of the variable \f(CWx\fP +assigned to the variable \f(CWf\fP in the initialization sequence +is the value of the global variable \f(CWx\fP, rather than the local \f(CWx\fP, +because the scope of the local variable \f(CWx\fP only starts after the full +declarator for the local \f(CWx\fP. +.R +.LE +.P +.H 2 "Common Block Entries" +.IX common blocks +.IX Fortran +A Fortran common block may be described by a debugging information +entry with the tag +.Cf DW_TAG_common_block . +The common block entry has a +.Cf DW_AT_name +attribute whose value is a null-terminated +string containing the common block name as it appears in the source program. +It also has a +.Cf DW_AT_location +attribute whose value describes the location of the beginning of the +common block. The common block entry owns debugging information +entries describing the variables contained within the common block. +.H 2 "Imported Declaration Entries" +.I +.IX declarations, imported +.IX imports +Some languages support the concept of importing into a given +module declarations made in a different module. +.R +.P +An imported declaration is represented by a debugging information +entry with the tag +.Cf DW_TAG_imported_declaration . +The entry for the imported declaration has a +.Cf DW_AT_name +attribute whose value +is a null-terminated string containing the name of the entity +whose declaration is being imported as it appears in the source +program. The imported declaration entry also has a +.Cf DW_AT_import +attribute, whose value is a reference to the debugging information +entry representing the declaration that is being imported. +.H 2 "Namelist Entries" +.I +.IX namelists +.IX Fortran90 +At least one language, Fortran90, has the concept of a namelist. +A namelist is an ordered list of the names of some set of declared objects. +The namelist object itself may be used as a replacement for the +list of names in various contexts. +.R +.P +A namelist is represented by a debugging information entry with +the tag +.Cf DW_TAG_namelist . +If the namelist itself has a name, the namelist entry has a +.Cf DW_AT_name +attribute, whose value is a null-terminated string containing the namelist's +name as it appears in the source program. +.P +Each name that is part of the namelist is represented by a debugging +information entry with the tag +.Cf DW_TAG_namelist_item . +Each such entry is a child of the namelist entry, and all of +the namelist item entries for a given namelist are ordered as were +the list of names they correspond to in the source program. +.P +Each namelist item entry contains a +.Cf DW_AT_namelist_item +attribute whose value is a reference to the debugging information +entry representing the declaration of the item whose name +appears in the namelist. +.OP +.H 1 "TYPE ENTRIES" +This section presents the debugging information entries +that describe program types: base types, modified types +and user-defined types. +.P +If the scope of the declaration of a named type begins sometime after +.IX scope +.IX declarations, scope +the low pc value +for the scope most closely enclosing the declaration, the +declaration may have a +.Cf DW_AT_start_scope +attribute. The value of this attribute is the offset in bytes of the beginning +of the scope for the declaration from the low pc value of the debugging +information entry that defines its scope. +.H 2 "Base Type Entries" +.I +.IX base types +.IX types, base +A base type is a data type that is not defined in terms of +other data types. Each programming language has a set of +base types that are considered to be built into that language. +.R +.P +A base type is represented by a debugging information entry +with the tag +.Cf DW_TAG_base_type . +A base type entry has a +.Cf DW_AT_name +attribute whose value is a null-terminated +string describing the name of the base type as recognized by +the programming language of the compilation unit containing +the base type entry. +.P +A base type entry also has a +.Cf DW_AT_encoding +attribute describing how the base type is encoded and is +to be interpreted. The value of this attribute is a constant. +The set of values and their meanings for the +.Cf DW_AT_encoding +.nr aX \n(Fg+1 +attribute is given in Figure \n(aX. +.DF +.TS +box center; +l l +lf(CW) l +. +Name Meaning +_ +DW_ATE_address linear machine address +DW_ATE_boolean true or false +DW_ATE_complex_float complex floating-point number +DW_ATE_float floating-point number +DW_ATE_signed signed binary integer +DW_ATE_signed_char signed character +DW_ATE_unsigned unsigned binary integer +DW_ATE_unsigned_char unsigned character +.TE +.FG "Encoding attribute values" +.DE +.P +All encodings assume the representation that is ``normal'' for +the target architecture. +.P +A base type entry has a +.Cf DW_AT_byte_size +attribute, whose value is a constant, +describing the size in bytes of the storage +unit used to represent an object of the given type. +.P +If the value of an object of the given type does not +fully occupy the storage unit described by the byte size attribute, +the base type entry may have a +.Cf DW_AT_bit_size +attribute and a +.Cf DW_AT_bit_offset +attribute, both of whose values are constants. +The bit size attribute describes the actual size in bits used +to represent a value of the given type. The bit offset +attribute describes the offset in bits of the high order +bit of a value of the given type from the high order bit +of the storage unit used to contain that value. +.I +.P +For example, the C type +.Cf int +on a machine that uses 32-bit integers would be +represented by a base type entry with a name +attribute whose value was ``\f(CWint\fP,'' an +encoding attribute whose value was +.Cf DW_ATE_signed +and a byte size attribute whose value was +.Cf 4 . +.R +.H 2 "Type Modifier Entries" +.IX type modifiers +.IX types, modifiers +A base or user-defined type may be modified in different +ways in different languages. A type modifier is represented +in DWARF by a debugging information entry with one of the +.nr aX \n(Fg+1 +tags given in Figure \n(aX. +.DF +.TS +box center; +l l +lf(CW) l +. +Tag Meaning +_ +DW_TAG_const_type C or C++ const qualified type +DW_TAG_packed_type Pascal packed type +DW_TAG_pointer_type The address of the object whose type is being modified +DW_TAG_reference_type A C++ reference to the object whose type is being modified +DW_TAG_volatile_type C or C++ volatile qualified type +.TE +.FG "Type modifier tags" +.DE +.P +.IX types, constant +.IX types, packed +.IX types, volatile +.IX types, pointer +.IX types, reference +Each of the type modifier entries has a +.Cf DW_AT_type +attribute, whose value is a reference to a debugging information +entry describing a base type, a user-defined type or another type +modifier. +.P +A modified type entry describing a pointer or reference type +may have a +.IX addresses, class +.Cf DW_AT_address_class +attribute +to describe how objects having the given pointer or reference type +ought to be dereferenced. +.P +When multiple type modifiers are chained together to modify +a base or user-defined type, they are ordered as if part of +a right-associative expression involving the base or user-defined +type. +.I +.P +As examples of how type modifiers are ordered, take the following +C declarations: +.R +.DS +.ta .5i +.5i +.5i +.5i +.5i +.5i +.5i +.5i +\f(CWconst char * volatile p;\fP + \fIwhich represents a volatile pointer to a constant character.\fP + \fIThis is encoded in DWARF as:\fP + \f(CWDW_TAG_volatile_type \(-> + DW_TAG_pointer_type \(-> + DW_TAG_const_type \(-> + DW_TAG_base_type\fP + +\f(CWvolatile char * const p;\fP + \fIon the other hand, represents a constant pointer + to a volatile character.\fP + \fIThis is encoded as:\fP + \f(CWDW_TAG_const_type \(-> + DW_TAG_pointer_type \(-> + DW_TAG_volatile_type \(-> + DW_TAG_base_type\fP + +.DE +.R +.H 2 "Typedef Entries" +.IX typedefs +Any arbitrary type named via a typedef is represented +by a debugging information entry with the tag +.Cf DW_TAG_typedef . +The typedef entry has a +.Cf DW_AT_name +attribute whose value is a null-terminated +string containing the name of the typedef as it appears in the +source program. +The typedef entry also contains a +.Cf DW_AT_type +attribute. +.P +If the debugging information entry for a typedef represents a +declaration of the type that is not also a definition, +it does not contain a type attribute. +.IX declarations, non-defining +.H 2 "Array Type Entries" +.I +.IX arrays +Many languages share the concept of an ``array,'' which is a +table of components of identical type. +.P +.R +An array type is represented by a debugging information entry with +the tag +.Cf DW_TAG_array_type . +.P +If a name has been given to the array type in the source program, then the +corresponding array type entry has a +.Cf DW_AT_name +attribute whose value is a +null-terminated string containing the array type name as it appears in the +source program. +.P +.IX arrays, ordering +The array type entry describing a multidimensional array may have a +.Cf DW_AT_ordering +attribute whose constant value is interpreted to mean either +row-major or column-major ordering of array elements. +The set of values and their meanings for the ordering attribute +.nr aX \n(Fg+1 +are listed in Figure \n(aX. +If no ordering attribute is present, the default ordering for +the source language (which is indicated by the +.Cf DW_AT_language +attribute of the enclosing compilation unit entry) +is assumed. +.DF +.TS +box center; +lf(CW) +. +DW_ORD_col_major +DW_ORD_row_major +.TE +.FG "Array ordering" +.DE +.P +The ordering attribute may optionally appear on one-dimensional arrays; it +will be ignored. +.P +An array type entry has a +.Cf DW_AT_type +attribute describing the type +of each element of the array. +.P +.IX arrays, stride +If the amount of storage allocated to hold each element of an object of +the given array type is different from the amount of storage that is normally +allocated to hold an individual object of the indicated element type, then +the array type entry has a +.Cf DW_AT_stride_size +attribute, whose constant value +represents the size in bits of each element of the array. +.P +If the size of the entire array can be determined statically at compile +time, the array type entry may have a +.Cf DW_AT_byte_size +attribute, whose constant value represents the total size in bytes of an +instance of the array type. +.P +.I +Note that if the size of the array can be determined statically at +compile time, this value can usually be computed by multiplying +the number of array elements by the size of each element. +.P +.R +Each array dimension is described by a debugging information +entry with either the tag +.IX subranges +.IX enumerations +.IX arrays, dimensions +.Cf DW_TAG_subrange_type +or the tag +.Cf DW_TAG_enumeration_type . +These entries are children of the array type entry and are +ordered to reflect the appearance of the dimensions in the source +program (i.e. leftmost dimension first, next to leftmost second, +and so on). +.P +.I +.IX C %c +In languages, such as ANSI-C, in which there is no concept of a +``multidimensional array,'' +an array of arrays may be represented by a debugging information entry +for a multidimensional array. +.R +.H 2 "Structure, Union, and Class Type Entries" +.I +The languages C, C++, and Pascal, among others, +allow the programmer to define types that +are collections of related components. In C and C++, these collections are +called ``structures.'' In Pascal, they are called ``records.'' The components +may be of different types. The components are called ``members'' in C and +C++, and ``fields'' in Pascal. +.P +.IX structures +.IX classes +.IX unions +.IX records +.IX C %c +.IX C++ %caa +.IX Pascal +The components of these collections each exist in their own space in +computer memory. The components of a C or C++ ``union'' all coexist in +the same memory. +.P +Pascal and other languages have a ``discriminated union,'' also called a +.IX variants +.IX discriminated unions +``variant record.'' Here, selection of a number of alternative substructures +(``variants'') is based on the value of a component that is not part of any of +those substructures (the ``discriminant''). +.P +Among the languages discussed in this document, +the ``class'' concept is unique to C++. A class is similar to a structure. +A C++ class or structure may have ``member functions'' which are subroutines +that are within the scope of a class or structure. +.R +.H 3 "General Structure Description" +Structure, union, and class types are represented by +debugging information entries with the tags +.Cf DW_TAG_structure_type , +.Cf DW_TAG_union_type +and +.Cf DW_TAG_class_type , +respectively. +If a name has been given to the structure, union, or class in the source +program, then the corresponding structure type, union type, or class type +entry has a +.Cf DW_AT_name +attribute whose value is a null-terminated string +containing the type name as it appears in the source program. +.P +If the size of an instance of the +structure type, union type, or class type entry can be determined +statically at compile time, the entry has a +.Cf DW_AT_byte_size +attribute whose constant value is the number of bytes required to +hold an instance of the structure, union, or class, and any padding bytes. +.I +.P +.IX structures, incomplete +.IX classes, incomplete +.IX unions, incomplete +For C and C++, an incomplete structure, union or class type is represented +by a structure, union or class entry that does not have +a byte size attribute and that has a +.Cf DW_AT_declaration +attribute. +.R +.P +The members of a structure, union, or class are represented by +debugging information entries that are owned by the corresponding +structure type, union type, or class type entry and appear in the same +order as the corresponding declarations in the source program. +.P +.I +.IX declarations, defining +.IX members, static data +.IX members, data +.IX members, functions +Data member declarations occurring within the declaration of a structure, +union or class type are considered to be ``definitions'' of those members, +with the exception of C++ ``static'' data members, whose definitions +appear outside of the declaration of the enclosing structure, union +or class type. Function member declarations appearing within a structure, +union or class type declaration are definitions only if the body +of the function also appears within the type declaration. +.R +.P +.IX declarations, non-defining +If the definition for a given member of the structure, union or class +does not appear within the body of the declaration, that member +also has a debugging information entry describing its definition. +That entry will have a +.Cf DW_AT_specification +attribute referencing +the debugging entry owned by the +body of the structure, union or class debugging entry and representing +a non-defining declaration of the data or function member. The +referenced entry will +not have information about the location of that member (low and high +pc attributes for function members, location descriptions for data +members) and will have a +.Cf DW_AT_declaration +attribute. +.H 3 "Derived Classes and Structures" +.IX classes, derived +.IX structures, derived +.IX inheritance +The class type or structure type entry that describes a derived class +or structure owns debugging information entries describing each of +the classes or structures it is derived from, ordered as they were +in the source program. Each such entry has the tag +.Cf DW_TAG_inheritance . +.P +An inheritance entry has a +.Cf DW_AT_type +attribute whose +value is a reference to the debugging information entry describing +the structure or class from which the parent structure or class +of the inheritance entry is derived. It also has a +.Cf DW_AT_data_member_location +attribute, whose value is a location description describing +the location of the beginning of +the data members contributed to the entire class by this +subobject relative to the beginning address of the data members of the +entire class. +.P +.IX accessibility +.IX virtuality +.IX classes, virtual base +An inheritance entry may have a +.Cf DW_AT_accessibility +attribute. +If no accessibility attribute is present, +private access is assumed. +If the structure or class referenced by the inheritance entry serves +as a virtual base class, the inheritance entry has a +.Cf DW_AT_virtuality +attribute. +.P +.I +In C++, a derived class may contain access declarations that +change the accessibility of individual class members from +the overall accessibility specified by the inheritance declaration. +A single access declaration may refer to a set of overloaded +names. +.R +.P +If a derived class or structure contains access declarations, +.IX access declarations +.IX C++ %caa +each such declaration may be represented by a debugging information +entry with the tag +.Cf DW_TAG_access_declaration . +Each such entry is a child of the structure or class type entry. +.P +An access declaration entry has a +.Cf DW_AT_name +attribute, whose value +is a null-terminated string representing the name used in the +declaration in the source program, including any class or structure +qualifiers. +.P +An access declaration entry also has a +.Cf DW_AT_accessibility +attribute +describing the declared accessibility of the named entities. +.H 3 "Friends" +.IX friends +.IX classes, friends +Each ``friend'' declared by +a structure, union or class type may be represented by +a debugging information entry that is a child of the structure, +union or class type entry; the friend entry has the tag +.Cf DW_TAG_friend. +.P +A friend entry has a +.Cf DW_AT_friend +attribute, whose value is a reference to the debugging information +entry describing the declaration of the friend. +.H 3 "Structure Data Member Entries" +.IX members, data +A data member (as opposed to a member function) is represented by +a debugging information entry with the tag +.Cf DW_TAG_member . +The member entry for a named member has a +.Cf DW_AT_name +attribute +whose value is a null-terminated string containing the member name +as it appears in the source program. If the member entry describes +a C++ anonymous union, the name attribute is omitted or consists +of a single zero byte. +.IX unions, anonymous +.IX anonymous unions +.P +The structure data member entry has a +.Cf DW_AT_type +attribute +to denote the type of that member. +.P +If the member entry is defined in the structure or class body, it has a +.Cf DW_AT_data_member_location +attribute whose value is a location +description that describes the location of that +member relative to the base address of the structure, union, or class that +most closely encloses the corresponding member declaration. +.I +.P +.IX locations, expressions +.IX locations, descriptions +The addressing expression represented by the location +description for a structure data member expects the base address +of the structure data member to be on the expression stack +before being evaluated. +.P +.IX unions +The location description for a data member of a union may be omitted, +since all data members of a union begin at the same address. +.R +.P +.IX bit fields +.IX members, bit fields +If the member entry describes a bit field, then that entry has the following +attributes: +.AL +.LI +A +.Cf DW_AT_byte_size +attribute whose constant value is the number of bytes that +contain an instance of the bit field and any padding bits. +.P +.I +The byte size attribute may be omitted if the size of the object containing +the bit field can be inferred from the type attribute of the data +member containing the bit field. +.R +.LI +A +.Cf DW_AT_bit_offset +attribute whose constant value is the number of bits +to the left of the leftmost (most significant) bit of the bit field value. +.LI +A +.Cf DW_AT_bit_size +attribute whose constant value is the number of bits occupied +by the bit field value. +.LE +.P +The location description for a bit field calculates the address of +an anonymous object containing the bit field. The address is +relative to the structure, union, or class that +most closely encloses the bit field declaration. The number +of bytes in this anonymous object is the value of the byte +size attribute of the bit field. The offset (in bits) +from the most significant bit of the +anonymous object to the most significant bit of the bit field is the +value of the bit offset attribute. +.I +.P +For example, take one possible representation of the following +structure definition in both big and little endian byte orders: +.DS +\f(CW +struct S { + int j:5; + int k:6; + int m:5; + int n:8; +};\fP +.DE +.P +In both cases, the location descriptions for the debugging information +entries for \f(CWj\fP, \f(CWk\fP, \f(CWm\fP and \f(CWn\fP +describe the address of +the same 32-bit word that contains all three members. +(In the big-endian case, +the location description addresses the most significant byte, in +the little-endian case, the least significant). +The following diagram shows the structure layout and lists the bit +offsets for each case. The offsets +are from the most significant bit of the object addressed by the location +description. +.PS +bitht = .3 +boxht = bitht +bitwid = .11 +nibwid = .75 * bitwid +bytewid = 8 * bitwid +boxwid = bytewid +define nibble X # nibble(len, "label", hi-left, hi-right, lo-left, lo-right, any) +N: box width $1*nibwid $2 $7 + { if $3 >= 0 then % "\s-4\|$3\s0" at N.w + (0,bitht/3) ljust % + } # curly on separate line for pic bug + { if $4 >= 0 then % "\s-4\|$4\s0" at N.e + (0,bitht/3) rjust % + } + { if $5 >= 0 then % "\s-4\|$5\s0" at N.w - (0,bitht/3) ljust % + } + { if $6 >= 0 then % "\s-4$6\|\s0" at N.e - (0,bitht/3) rjust % + } +X +define tbox X # tbox(width,"label", any) +T: box width $1*nibwid ht 1/6 $3 invis + { $2 at T.w ljust + } +X +.PE +.DS +.PS + down +H: tbox(20,"Bit Offsets:") + tbox(20,"\f(CW j:0\fP") + tbox(20,"\f(CW k:5\fP") + tbox(20,"\f(CW m:11\fP") + tbox(20,"\f(CW n:16\fP") + right +H: tbox(32, "Big-Endian", with .w at H.e) +H: nibble(5,"\f(CWj\fP",0,-1,31,-1,with .nw at H.sw) +H: nibble(6,"\f(CWk\fP",-1,-1,26,-1) +H: nibble(5,"\f(CWm\fP",-1,-1,20,-1) +H: nibble(8,"\f(CWn\fP",-1,-1,15,-1) +H: nibble(8,"\fIpad\fP",-1,-1,7,0) +.PE +.DE +.DS +.PS + down +H: tbox(20,"Bit Offsets:") + tbox(20,"\f(CW j:27\fP") + tbox(20,"\f(CW k:21\fP") + tbox(20,"\f(CW m:16\fP") + tbox(20,"\f(CW n:8\fP") + right +H: tbox(32, "Little-Endian", with .w at H.e) +H: nibble(8,"\f2pad\fP",-1,-1,31,-1, with .nw at H.sw) +H: nibble(8,"\f(CWn\fP",-1,-1,23,-1) +H: nibble(5,"\f(CWm\fP",-1,-1,15,-1) +H: nibble(6,"\f(CWk\fP",-1,-1,10,-1) +H: nibble(5,"\f(CWj\fP",-1,0,4,0) +.PE +.DE +.R +.H 3 "Structure Member Function Entries" +.IX subroutines, members +.IX members, functions +.IX members, locations +A member function is represented in the debugging information by a +debugging information entry with the tag +.Cf DW_TAG_subprogram . +The member function entry may contain the same attributes and follows +the same rules as non-member global subroutine entries (see section 3.3). +.P +.IX virtuality +.IX virtual functions +If the member function entry describes a virtual function, then that entry +has a +.Cf DW_AT_virtuality +attribute. +.P +An entry for a virtual function also has a +.Cf DW_AT_vtable_elem_location +attribute whose value contains a location +description yielding the address of the slot for the function +within the virtual function table for the enclosing class or structure. +.P +.IX declarations, defining +If a subroutine entry represents the defining declaration +of a member function and that definition appears outside +of the body of the enclosing class or structure declaration, +the subroutine entry has a +.Cf DW_AT_specification +attribute, whose value is a reference to the debugging information +entry representing the declaration of this function member. The +referenced entry will be a child of some class or structure +type entry. +.P +Subroutine entries containing the +.Cf DW_AT_specification +attribute do not need to duplicate information provided by the +declaration entry referenced by the specification attribute. +In particular, such entries do not need to contain +attributes for the name or return type of the function member whose +definition they represent. +.H 3 "Class Template Instantiations" +.I +.IX C++ %caa +.IX templates +In C++ a class template is a generic +definition of a class type that +is instantiated differently when an instance of the class +is declared or defined. The generic description of the class +may include both parameterized types and parameterized constant +values. DWARF does not represent the generic +template definition, but does represent each instantiation. +.R +.P +A class template instantiation is represented by a debugging information +with the tag +.Cf DW_TAG_class_type . +With four exceptions, +such an entry will contain the same attributes and have the same +types of child entries as would an entry for a class type defined +explicitly using the instantiation types and values. +The exceptions are: +.AL +.LI +Each formal parameterized type declaration appearing in the +template definition is represented by a debugging information entry +with the tag +.Cf DW_TAG_template_type_parameter . +Each such entry has a +.Cf DW_AT_name +attribute, whose value is a null-terminated +string containing the name of the formal type parameter as it +appears in the source program. The template type parameter +entry also has a +.Cf DW_AT_type +attribute describing the actual type by +which the formal is replaced for this instantiation. +.LI +Each formal parameterized value declaration appearing +in the templated definition is represented by a debugging information +entry with the tag +.Cf DW_TAG_template_value_parameter . +Each such entry has a +.Cf DW_AT_name +attribute, whose value is a null-terminated +string containing the name of the formal value parameter as it +appears in the source program. The template value parameter +entry also has a +.Cf DW_AT_type +attribute describing the type of the parameterized +value. Finally, the template value parameter entry has a +.Cf DW_AT_const_value +attribute, whose value is the actual constant value of the value +parameter for this instantiation as represented on the target +architecture. +.LI +.IX compilation units +If the compiler has generated a special compilation unit +to hold the template instantiation and that compilation unit +has a different name +from the compilation unit containing the template definition, +the name attribute for the debugging entry representing +that compilation unit should be empty or omitted. +.LI +.IX declarations, coordinates +If the class type entry representing the template instantiation +or any of its child entries +contain declaration coordinate attributes, those attributes +should refer to the source for the template definition, not +to any source generated artificially by the compiler. +.LE +.H 3 "Variant Entries" +.IX variants +.IX discriminated unions +A variant part of a structure is represented by a debugging +information entry with the tag +.Cf DW_TAG_variant_part +and is owned by the corresponding structure type +entry. +.P +.IX discriminants +If the variant part has a discriminant, the discriminant is represented +by a separate debugging information entry which is a child of +the variant part entry. This entry has the form of a structure data member +entry. +The variant part entry will have a +.Cf DW_AT_discr +attribute whose value is a +reference to the member entry for the discriminant. +.P +If the variant part +does not have a discriminant (tag field), the variant part entry has a +.Cf DW_AT_type +attribute to represent the tag type. +.P +Each variant of a particular variant part is represented by a debugging +information entry with the tag +.Cf DW_TAG_variant +and is a child of the variant part entry. The value that selects a +given variant may be represented in one of three ways. The +variant entry may have a +.Cf DW_AT_discr_value +attribute whose value represents a single case label. +The value of this attribute +is encoded as an LEB128 number. The number is signed if the tag +type for the variant part containing this variant is +a signed type. The number is unsigned if the tag type is an unsigned type. +.P +Alternatively, the variant entry may contain a +.Cf DW_AT_discr_list +attribute, whose value represents a list of discriminant values. +This list is represented by any of the block forms and may contain +a mixture of case labels and label ranges. Each item on the list +is prefixed with a discriminant value descriptor that determines whether +the list item represents a single label or a label range. +A single case label is represented as an LEB128 +number as defined above +for the +.Cf DW_AT_discr_value +attribute. A label range is represented by two LEB128 numbers, +the low value of the range followed by the high value. Both values +follow the rules for signedness just described. +The discriminant value descriptor is a constant that may have +.nr aX \n(Fg+1 +one of the values given in Figure \n(aX. +.DF +.TS +center box; +lf(CW) +. +DW_DSC_label +DW_DSC_range +.TE +.FG "Discriminant descriptor values" +.DE +.P +If a variant entry has neither a +.Cf DW_AT_discr_value +attribute nor a +.Cf DW_AT_discr_list +attribute, or if it has a +.Cf DW_AT_discr_list +attribute with 0 size, the variant is a default variant. +.P +The components selected by a particular variant are represented +by debugging information entries owned by the corresponding variant +entry and appear in the same order as the corresponding declarations in +the source program. +.H 2 "Enumeration Type Entries" +.I +.IX enumerations +An ``enumeration type'' is a scalar that can assume one of a fixed number of +symbolic values. +.P +.R +An enumeration type is represented by a debugging information entry +with the tag +.Cf DW_TAG_enumeration_type . +.P +If a name has been given to the enumeration type in the source program, +then the corresponding enumeration type entry has a +.Cf DW_AT_name +attribute +whose value is a null-terminated string containing the enumeration type +name as it appears in the source program. +These entries also have a +.Cf DW_AT_byte_size +attribute whose +constant value is the number of bytes required to hold an +instance of the enumeration. +.P +Each enumeration literal is represented by a debugging information +entry with the tag +.Cf DW_TAG_enumerator . +Each such entry is a child of the enumeration type entry, and +the enumerator entries appear in the same order as the declarations of +the enumeration literals in the source program. +.P +Each enumerator entry has a +.Cf DW_AT_name +attribute, whose value is +a null-terminated string containing the name of the enumeration +literal as it appears in the source program. Each enumerator +entry also has a +.Cf DW_AT_const_value +attribute, whose value is the actual numeric value of the enumerator +as represented on the target system. +.H 2 "Subroutine Type Entries" +.I +.IX subroutines, types +It is possible in C to declare pointers to subroutines that return a value +of a specific type. In both ANSI C and C++, it is possible to declare +pointers to subroutines that not only return a value of a specific type, +but accept only arguments of specific types. The type of such pointers +would be described with a ``pointer to'' modifier applied to a user-defined +type. +.R +.P +A subroutine type is represented by a debugging information entry +with the tag +.Cf DW_TAG_subroutine_type . +If a name has been given to the subroutine type in the source program, +then the corresponding subroutine type entry has a +.Cf DW_AT_name +attribute +whose value is a null-terminated string containing the subroutine type +name as it appears in the source program. +.P +.IX subroutines, return types +If the subroutine type describes a function that returns a value, then +the subroutine type entry has a +.Cf DW_AT_type +attribute +to denote the type returned by the subroutine. +If the types of the arguments are necessary to describe the subroutine type, +then the corresponding subroutine type entry owns debugging +information entries that describe the arguments. +These debugging information entries appear in the order +that the corresponding argument types appear in the source program. +.P +.I +.IX C %c +.IX subroutines, prototypes +In ANSI-C there is a difference between the types of functions +declared using function prototype style declarations and those +declared using non-prototype declarations. +.P +.R +A subroutine entry +declared with a function prototype style declaration may have a +.Cf DW_AT_prototyped +attribute, whose value is a flag. +.P +Each debugging information entry +owned by a subroutine type entry has a tag whose value has one of +two possible interpretations. +.AL +.LI +.IX parameters, formal +Each debugging information entry that is owned by a subroutine type entry and +that defines a single argument of a specific type has the tag +.Cf DW_TAG_formal_parameter . +.P +The formal parameter entry has a type attribute +to denote the type of the corresponding formal parameter. +.LI +The unspecified parameters of a variable parameter list are represented by a +debugging information entry owned by the subroutine type entry with the tag +.Cf DW_TAG_unspecified_parameters . +.IX parameters, unspecified +.LE +.H 2 "String Type Entries" +.I +.IX string types +.IX Fortran +A ``string'' is a sequence of characters that have specific semantics and +operations that separate them from arrays of characters. +Fortran is one of +the languages that has a string type. +.R +.P +A string type is represented by a debugging information entry +with the tag +.Cf DW_TAG_string_type . +If a name has been given to the string type in the source program, +then the corresponding string type entry has a +.Cf DW_AT_name +attribute +whose value is a null-terminated string containing the string type +name as it appears in the source program. +.P +The string type entry may have a +.Cf DW_AT_string_length +attribute whose value is a location description +yielding the location where the length of the string +is stored in the program. The string type entry may also have a +.Cf DW_AT_byte_size +attribute, whose constant value is the size in bytes of the data +to be retrieved from the location referenced by the string length +attribute. If no byte size attribute is present, the size of the +data to be retrieved is the same as the size of an address on +the target machine. +.P +If no string length attribute is present, the string type entry may have +a +.Cf DW_AT_byte_size +attribute, whose constant value is the length in bytes of +the string. +.H 2 "Set Entries" +.I +Pascal provides the concept of a ``set,'' which represents a group of +values of ordinal type. +.P +.R +.IX Pascal +.IX set types +A set is represented by a debugging information entry +with the tag +.Cf DW_TAG_set_type . +If a name has been given to the set type, +then the set type entry has a +.Cf DW_AT_name +attribute +whose value is a null-terminated string containing the set type name +as it appears in the source program. +.P +The set type entry has a +.Cf DW_AT_type +attribute to denote the type +of an element of the set. +.P +If the amount of storage allocated to hold each element of an object of +the given set type is different from the amount of storage that is normally +allocated to hold an individual object of the indicated element type, then +the set type entry has a +.Cf DW_AT_byte_size +attribute, whose constant value +represents the size in bytes of an instance of the set type. +.H 2 "Subrange Type Entries" +.I +Several languages support the concept of a ``subrange'' type object. +These objects can represent a subset of the values that an +object of the basis type for the subrange can represent. +Subrange type entries may also be used to represent the bounds +of array dimensions. +.R +.P +.IX subranges +A subrange type is represented by a debugging information entry +with the tag +.Cf DW_TAG_subrange_type . +If a name has been given to the subrange type, +then the subrange type entry has a +.Cf DW_AT_name +attribute +whose value is a null-terminated string containing the subrange type name +as it appears in the source program. +.P +The subrange entry may have a +.Cf DW_AT_type +attribute to describe +the type of object of whose values this subrange is a subset. +.P +If the amount of storage allocated to hold each element of an object of +the given subrange type is different from the amount of storage that is normally +allocated to hold an individual object of the indicated element type, then +the subrange type entry has a +.Cf DW_AT_byte_size +attribute, whose constant value +represents the size in bytes of each element of the subrange type. +.P +The subrange entry may have the attributes +.Cf DW_AT_lower_bound +and +.Cf DW_AT_upper_bound +to describe, respectively, the lower and upper bound values +of the subrange. +The +.Cf DW_AT_upper_bound +attribute may be replaced by a +.Cf DW_AT_count +attribute, whose value describes the number of elements in +the subrange rather than the value of the last element. +If a bound or count value is described by a constant +not represented in the program's address space and can +be represented by one of the constant attribute forms, then the value +of the lower or upper bound or count attribute may be one of the constant +types. Otherwise, the value of the lower or upper bound or count +attribute is a reference to a debugging information entry describing +an object containing the bound value or itself describing a constant +value. +.P +If either the lower or upper bound or count values are missing, the +bound value is assumed to be a language-dependent default +constant. +.P +.I +.IX C %c +.IX C++ %caa +.IX Fortran +The default lower bound value for C or C++ is 0. For Fortran, +it is 1. No other default values are currently defined by DWARF. +.R +.P +If the subrange entry has no type attribute describing the basis +type, the basis type is assumed to be the same as the object +described by the lower bound attribute (if it references an object). +If there is no lower bound attribute, or it does not reference +an object, the basis type is the type of the upper bound or count +attribute +(if it references an object). If there is no upper bound or count attribute +or it does not reference an object, the type is assumed to be +the same type, in the source language +of the compilation unit containing the subrange entry, +as a signed integer with the same size +as an address on the target machine. +.H 2 "Pointer to Member Type Entries" +.I +In C++, a pointer to a data or function member of a class or +structure is a unique type. +.P +.R +.IX C++ %caa +.IX members, pointers to +.IX pointers to members +A debugging information entry +representing the type of an object that is a pointer to a structure +or class member has the tag +.Cf DW_TAG_ptr_to_member_type . +.P +If the pointer to member type has a name, the pointer to member entry +has a +.Cf DW_AT_name +attribute, whose value is a null-terminated string +containing the type name as it appears in the source program. +.P +The pointer to member entry has a +.Cf DW_AT_type +attribute to describe +the type of the class or structure member to which objects +of this type may point. +.P +The pointer to member entry also has a +.Cf DW_AT_containing_type +attribute, whose value is a reference to a debugging information +entry for the class or structure to whose members objects of +this type may point. +.P +Finally, the pointer to member entry has a +.Cf DW_AT_use_location +attribute whose value is a location description that computes +the address of the member of the class or structure to which the +pointer to member type entry can point. +.P +.I +The method used to find the address of a given member +of a class or structure is common to any instance of that +class or structure and to any instance of the pointer or +member type. The method is thus associated +with the type entry, rather than with each instance of the type. +.P +The +.Cf DW_AT_use_location +expression, however, cannot be used on its own, but must +be used in conjunction with the location expressions for +a particular object of the given pointer to member type +and for a particular structure or class instance. The +.Cf DW_AT_use_location +attribute expects two values to be pushed onto the location expression +stack before the +.Cf DW_AT_use_location +expression is evaluated. The first value pushed should be +the value of the pointer to member object itself. +The second value pushed should be the base address of the entire +structure or union instance containing the member whose +address is being calculated. +.P +So, for an expression like +.DS + \f(CWobject.*mbr_ptr\fP +.DE +where \f(CWmbr_ptr\fP has some pointer to member type, +a debugger should: +.AL +.LI +Push the value of +.Cf mbr_ptr +onto the location expression stack. +.LI +Push the base address of +.Cf object +onto the location expression stack. +.LI +Evaluate the +.Cf DW_AT_use_location +expression for the type of +.Cf mbr_ptr . +.LE +.R +.H 2 "File Type Entries" +.I +Some languages, such as Pascal, provide a first class data type +to represent files. +.R +.P +.IX Pascal +.IX file types +A file type is represented by a debugging information entry +with the tag +.Cf DW_TAG_file_type. +If the file type has a name, the file type entry +has a +.Cf DW_AT_name +attribute, whose value is a null-terminated string +containing the type name as it appears in the source program. +.P +The file type entry has a +.Cf DW_AT_type +attribute describing the type +of the objects contained in the file. +.P +The file type entry also has a +.Cf DW_AT_byte_size +attribute, whose value +is a constant representing the size in bytes of an instance +of this file type. +.OP +.H 1 "OTHER DEBUGGING INFORMATION" +This section describes debugging information that +is not represented in the form of debugging information +entries and is not contained within the +.Cf .debug_info +section. +.H 2 "Accelerated Access" +.I +.IX accelerated access +A debugger frequently needs to find the debugging information for +a program object defined outside of the compilation unit +where the debugged program is currently stopped. Sometimes +it will know only the name of the object; sometimes only the address. +To find the debugging information +associated with a global object by name, using the DWARF debugging information +entries alone, a debugger would need +to run through all entries at the highest scope within each +compilation unit. For lookup by address, for a subroutine, +a debugger can use the low and high pc attributes +of the compilation unit entries to quickly narrow down the search, +but these attributes only cover +the range of addresses for the text associated with a compilation +unit entry. To find the debugging information associated with a +data object, an exhaustive search would be needed. +Furthermore, any search through debugging information entries for +different compilation units within a large program +would potentially require the access of many memory pages, +probably hurting debugger performance. +.R +.P +To make lookups of program objects by name or by address faster, +a producer of DWARF information may provide two different types +of tables containing information about the debugging information +entries owned by a particular compilation unit entry in a more condensed +format. +.H 3 "Lookup by Name" +.IX lookup, by name +For lookup by name, a table is maintained in a separate +object file section called +.Cf .debug_pubnames . +.IX \f(CW.debug_pubnames\fP %debugap +The table consists of sets of variable length entries, each +set describing the names of global objects whose definitions +or declarations are represented by debugging information entries +owned by a single compilation unit. Each set begins +with a header containing four values: the total length of the entries +for that set, not including the length field itself, a version number, +the offset from the beginning of the +.Cf .debug_info +.IX \f(CW.debug_info\fP %debugai +section of the compilation unit entry referenced by the set and +the size in bytes of the contents of the +.Cf .debug_info +section generated to represent that compilation unit. This +header is followed by a variable number of offset/name pairs. +Each pair consists of the offset from the beginning of the compilation +unit entry corresponding to the current set to the +debugging information entry for +the given object, followed by a null-terminated character +string representing the name of the object as given by +the +.Cf DW_AT_name +attribute of the referenced debugging entry. +Each set of names is terminated by zero. +.P +.IX C++ %caa +.IX members, static data +In the case of the name of a static data member or function member +of a C++ structure, class or union, the name presented +in the +.Cf .debug_pubnames +section is not the simple name given by the +.Cf DW_AT_name +attribute of the referenced debugging entry, but rather +the fully class qualified name of the data or function member. +.IX identifiers, names +.H 3 "Lookup by Address" +.IX lookup, by address +For lookup by address, a table is maintained in a separate +object file section called +.Cf .debug_aranges . +.IX \f(CW.debug_aranges\fP %debugaar +The table consists of sets of variable length entries, each +set describing the portion of the program's address space that +is covered by a single compilation unit. Each set begins +with a header containing five values: +.AL +.LI +The total length of the entries +for that set, not including the length field itself. +.LI +A version number. +.LI +The offset from the beginning of the +.Cf .debug_info +.IX \f(CW.debug_info\fP %debugai +section of the compilation unit entry referenced by the set. +.LI +The size in bytes of an address on the target architecture. For +segmented addressing, this is the size of the offset portion of the +.IX addresses, offset portion +.IX addresses, size of +address. +.LI +.IX address space, segmented +.IX segmented address space +The size in bytes of a segment descriptor on the target architecture. +If the target system uses a flat address space, this value is 0. +.LE +.P +This +header is followed by a variable number of address +range descriptors. Each descriptor is a pair consisting of +the beginning address +of a range of text or data covered by some entry owned +by the corresponding compilation unit entry, followed by the length +of that range. A particular set is terminated by an entry consisting +of two zeroes. By scanning the table, a debugger can quickly +decide which compilation unit to look in to find the debugging information +for an object that has a given address. +.H 2 "Line Number Information" +.I +.IX line number information +A source-level debugger will need to know how to associate statements in +the source files with the corresponding machine instruction addresses in +the executable object or the shared objects used by that executable +object. Such an association would make it possible for the debugger user +to specify machine instruction addresses in terms of source statements. +This would be done by specifying the line number and the source file +containing the statement. The debugger can also use this information to +display locations in terms of the source files and to single step from +statement to statement. +.R +.P +As mentioned in section 3.1, above, +the line number information generated for a compilation unit +is represented in the \f(CW.debug_line\fP section of an object file and is +referenced by a corresponding compilation unit debugging information entry +in the \f(CW.debug_info\fP section. +.IX \f(CW.debug_info\fP %debugai +.IX \f(CW.debug_line\fP %debugali +.I +.P +If space were not a consideration, the information +provided in the +.Cf .debug_line +section could be represented as a large matrix, +with one row for each instruction in the emitted +object code. The matrix would have columns for: +.DL +.LI +the source file name +.LI +the source line number +.LI +the source column number +.LI +whether this instruction is the beginning of a source statement +.LI +whether this instruction is the beginning of a basic block. +.LE +.P +Such a matrix, however, would be impractically large. We shrink it with +two techniques. First, we delete from the matrix each row whose file, +line and source column information is identical with that of its predecessors. +Second, we design a byte-coded language for a state machine and store a stream +of bytes in the object file instead of the matrix. This language can be +much more compact than the matrix. When a consumer of the statement +information executes, it must ``run'' the state machine to generate +the matrix for each compilation unit it is interested in. The concept +of an encoded matrix also leaves room for expansion. In the future, +columns can be added to the matrix to encode other things that are +related to individual instruction addresses. +.R +.H 3 "Definitions" +.IX line number information, definitions +The following terms are used in the description of the line number information +format: +.VL 20 +.LI "state machine" +The hypothetical machine used by a consumer of the line number information +to expand the byte-coded instruction stream into a +matrix of line number information. +.LI "statement program" +A series of byte-coded line number information instructions representing one +compilation unit. +.LI "basic block" +A sequence of instructions that is entered only at the first instruction +and exited only at the last instruction. We define a procedure invocation +to be an exit from a basic block. +.LI "sequence" +A series of contiguous target machine instructions. One compilation +unit may emit multiple sequences (that is, not all instructions within +a compilation unit are assumed to be contiguous). +.LI "sbyte" +Small signed integer. +.LI "ubyte" +Small unsigned integer. +.LI "uhalf" +Medium unsigned integer. +.LI "sword" +Large signed integer. +.LI "uword" +Large unsigned integer. +.LI "LEB128" +.IX LEB128 +Variable length signed and unsigned data. See section 7.6. +.LE +.H 3 "State Machine Registers" +.IX line number information, state machine registers +The statement information state machine has the following registers: +.VL 20 +.LI "\f(CWaddress\fP" +The program-counter value corresponding to a machine instruction generated +by the compiler. +.LI "\f(CWfile\fP" +An unsigned integer indicating the identity of the source file corresponding +to a machine instruction. +.IX source, files +.LI "\f(CWline\fP" +.IX source, lines +An unsigned integer indicating a source line number. Lines are numbered +beginning at 1. The compiler may emit the value 0 in cases where an +instruction cannot be attributed to any source line. +.LI "\f(CWcolumn\fP" +.IX source, columns +An unsigned integer indicating a column number within a source line. +Columns are numbered beginning at 1. The value 0 is reserved to indicate +that a statement begins at the ``left edge'' of the line. +.LI "\f(CWis_stmt\fP" +A boolean indicating that the current instruction is the beginning of a +statement. +.LI "\f(CWbasic_block\fP" +A boolean indicating that the current instruction is the beginning of +a basic block. +.LI "\f(CWend_sequence\fP" +A boolean indicating that the current address is that of the first +byte after the end of a sequence of target machine instructions. +.LE +.P +At the beginning of each sequence within a statement program, the +state of the registers is: +.DS +.TS +; +lf(CW) l. +address 0 +file 1 +line 1 +column 0 +is_stmt determined by \f(CWdefault_is_stmt\fP in the statement program prologue +basic_block ``false'' +end_sequence ``false'' +.TE +.DE +.H 3 "Statement Program Instructions" +The state machine instructions in a statement program belong to one +of three categories: +.VL 20 +.LI "special opcodes" +.IX line number information, special opcodes +These have a ubyte opcode field and no arguments. +Most of the instructions in a statement program are special opcodes. +.LI "standard opcodes" +.IX line number information, standard opcodes +These have a ubyte opcode field which may be followed by zero or more +LEB128 arguments (except for +.Cf DW_LNS_fixed_advance_pc , +see below). +The opcode implies the number of arguments and their +meanings, but the statement program prologue also specifies the number +of arguments for each standard opcode. +.LI "extended opcodes" +.IX line number information, extended opcodes +These have a multiple byte format. The first byte is zero; +the next bytes are an unsigned LEB128 integer giving the number of bytes +in the instruction itself (does not include the first zero byte or the size). +The remaining bytes are the instruction itself. +.LE +.H 3 "The Statement Program Prologue" +.IX line number information, prologue +The optimal encoding of line number information depends to a certain +degree upon the architecture of the target machine. The statement program +prologue provides information used by consumers in decoding the statement +program instructions for a particular compilation unit and also provides +information used throughout the rest of the statement program. The statement +program for each compilation unit begins with a prologue containing the +following fields in order: +.AL +.LI +.Cf total_length +(uword) +.br +The size in bytes of the statement information for this compilation unit +(not including the +.Cf total_length +field itself). +.LI +.Cf version +(uhalf) +.br +Version identifier for the statement information format. +.LI +.Cf prologue_length +(uword) +.br +The number of bytes following the +.Cf prologue_length +field to the beginning of the first byte of the statement program itself. +.LI +.Cf minimum_instruction_length +(ubyte) +.br +The size in bytes of the smallest target machine instruction. Statement +program opcodes that alter the +.Cf address +register first multiply their operands by this value. +.LI +.Cf default_is_stmt +(ubyte) +.br +The initial value of the +.Cf is_stmt +register. +.P +.I +A simple code generator +that emits machine instructions in the order implied by the source program +would set this to ``true,'' and every entry in the matrix would represent +a statement boundary. A pipeline scheduling code generator would set +this to ``false'' and emit a specific statement program opcode for each +instruction that represented a statement boundary. +.R +.LI +.Cf line_base +(sbyte) +.br +This parameter affects the meaning of the special opcodes. See below. +.LI +.Cf line_range +(ubyte) +.br +This parameter affects the meaning of the special opcodes. See below. +.LI +.Cf opcode_base +(ubyte) +.br +The number assigned to the first special opcode. +.LI +.Cf standard_opcode_lengths +(array of ubyte) +.br +This array specifies the number of LEB128 operands for each of +the standard opcodes. The first element of the array corresponds +to the opcode whose value is 1, and the last element corresponds +to the opcode whose value is +.Cf "opcode_base - 1" . +By increasing +.Cf opcode_base , +and adding elements to this array, new standard opcodes +can be added, while allowing consumers who do not know about these +new opcodes to be able to skip them. +.LI +.Cf include_directories +(sequence of path names) +.br +The sequence contains an entry for each path that was searched +for included source files in this compilation. (The paths include +those directories specified explicitly by the user for the compiler +to search and those the compiler searches without explicit direction). +Each path entry is either a full +path name or is relative to the current directory of the compilation. +The current directory of the compilation is understood to be the first entry +and is not explicitly represented. +Each entry is a null-terminated +string containing a full path name. The last entry is followed by +a single null byte. +.LI +.Cf file_names +(sequence of file entries) +.br +.IX source, files +The sequence contains an entry for each source file that contributed +to the statement information for this compilation unit or is +used in other contexts, such as in a declaration coordinate +or a macro file inclusion. Each entry +has a null-terminated string containing the file name, +an unsigned LEB128 number representing the directory index of the +directory in which the file was found, +an unsigned LEB128 number representing the time of last modification for +the file and an unsigned LEB128 number representing the length in +bytes of the file. A compiler may choose to emit LEB128(0) for the +time and length fields to indicate that this information is not +available. The last entry is followed by a single null byte. +.P +The directory index represents an entry in the +.Cf include_directories +section. The index is LEB128(0) if the file was found in +the current directory of the compilation, LEB128(1) if it was +found in the first directory in the +.Cf include_directories +section, and so on. The directory index is ignored for file names +that represent full path names. +.P +The statement program assigns numbers to each of the file entries +in order, beginning with 1, and uses those numbers instead of file +names in the +.Cf file +register. +.P +A compiler may generate a single null byte for the file names field +and define file names using the extended opcode +.Cf DEFINE_FILE . +.LE +.H 3 "The Statement Program" +As stated before, the goal of a statement program is to build a +matrix representing +one compilation unit, which may have produced multiple sequences of +target-machine instructions. Within a sequence, addresses may only increase. +(Line numbers may decrease in cases of pipeline scheduling.) +.H 4 "Special Opcodes" +.IX line number information, special opcodes +Each 1-byte special opcode has the following effect on the state machine: +.AL +.LI +Add a signed integer to the +.Cf line +register. +.LI +Multiply an unsigned integer by the +.Cf minimum_instruction_length +field of the statement program prologue and +add the result to the +.Cf address +register. +.LI +Append a row to the matrix using the current values of the state machine +registers. +.LI +Set the +.Cf basic_block +register to ``false.'' +.LE +.P +All of the special opcodes do those same four things; +they differ from one another +only in what values they add to the +.Cf line +and +.Cf address +registers. +.P +.I +Instead of assigning a fixed meaning to each special opcode, the statement +program uses several +parameters in the prologue to configure the instruction set. There are two +reasons for this. +First, although the opcode space available for special opcodes now +ranges from 10 through 255, the lower bound may increase if one adds new +standard opcodes. Thus, the +.Cf opcode_base +field of the statement program +prologue gives the value of the first special opcode. +Second, the best choice of special-opcode meanings depends on the target +architecture. For example, for a RISC machine where the compiler-generated code +interleaves instructions from different lines to schedule the pipeline, +it is important to be able to add a negative value to the +.Cf line +register +to express the fact that a later instruction may have been emitted for an +earlier source line. For a machine where pipeline scheduling never occurs, +it is advantageous to trade away the ability to decrease the +.Cf line +register +(a standard opcode provides an alternate way to decrease the line number) in +return for the ability to add larger positive values to the +.Cf address +register. To permit this variety of strategies, the statement program prologue +defines a +.Cf line_base +field that specifies the minimum value which a special opcode can add +to the +.Cf line +register and a +.Cf line_range +field that defines the range of +values it can add to the +.Cf line +register. +.R +.P +A special opcode value is chosen based on the amount that needs to +be added to the +.Cf line +and +.Cf address +registers. The maximum line increment +for a special opcode is the value of the +.Cf line_base +field in the +prologue, plus the value of the +.Cf line_range +field, minus 1 +(\f(CWline base + line range - 1\fP). If the desired line increment +is greater than the maximum line increment, a standard opcode +must be used instead of a special opcode. +The ``address advance'' is calculated by dividing the desired address +increment by the +.Cf minimum_instruction_length +field from the +prologue. The special opcode is then calculated using the following +formula: +.br + \f(CWopcode = (desired line increment - line_base) + +.br + (line_range * address advance) + opcode_base\fP +.br +If the resulting opcode is greater than 255, a standard opcode +must be used instead. +.P +To decode a special opcode, subtract the +.Cf opcode_base +from +the opcode itself. The amount to increment the +.Cf address +register is +the adjusted opcode divided by the +.Cf line_range . +The amount to +increment the +.Cf line +register is the +.Cf line_base +plus the result +of the adjusted opcode modulo the +.Cf line_range . +That is, +.br + \f(CWline increment = line_base + (adjusted opcode % line_range)\fP +.br +.P +.I +As an example, suppose that the +.Cf opcode_base +is 16, +.Cf line_base +is -1 and +.Cf line_range +is 4. +This means that we can use a special opcode whenever two successive +rows in the matrix have source line numbers differing by any value within +the range [-1, 2] (and, because of the limited number of opcodes available, +when the difference between addresses is within the range [0, 59]). +.P +The opcode mapping would be: +.R +.DS +.TS +box center; +l l l +nf(CW) nf(CW) nf(CW) +. +Opcode Line advance Address advance +_ +16 -1 0 +17 0 0 +18 1 0 +19 2 0 +20 -1 1 +21 0 1 +22 1 1 +23 2 1 +... ... ... +253 0 59 +254 1 59 +255 2 59 +.TE +.DE +.P +There is no requirement that the expression \f(CW255 - line_base + 1\fP be an +integral multiple of +.Cf line_range . +.H 4 "Standard Opcodes" +.IX line number information, standard opcodes +There are currently 9 standard ubyte opcodes. In the future +additional ubyte opcodes may be defined by setting the +.Cf opcode_base +field in the statement program +prologue to a value greater than 10. +.AL +.LI +.Cf DW_LNS_copy +.br +Takes no arguments. Append a row to the matrix using the current values of +the state-machine registers. Then set the +.Cf basic_block +register to ``false.'' +.LI +.Cf DW_LNS_advance_pc +.br +Takes a single unsigned LEB128 operand, +multiplies it by the +.Cf minimum_instruction_length +field of the prologue, and adds the result to the +.Cf address +register of the state machine. +.LI +.Cf DW_LNS_advance_line +.br +Takes a single signed LEB128 operand and adds +that value to the +.Cf line +register of the state machine. +.LI +.Cf DW_LNS_set_file +.br +Takes a single unsigned LEB128 operand and stores +it in the +.Cf file +register of the state machine. +.LI +.Cf DW_LNS_set_column +.br +Takes a single unsigned LEB128 operand and stores +it in the +.Cf column +register of the state machine. +.LI +.Cf DW_LNS_negate_stmt +.br +Takes no arguments. +Set the +.Cf is_stmt +register of the state machine to the +logical negation of its current value. +.LI +.Cf DW_LNS_set_basic_block +.br +Takes no arguments. Set the +.Cf basic_block +register of the state machine to ``true.'' +.LI +.Cf DW_LNS_const_add_pc +.br +Takes no arguments. +Add to the +.Cf address +register of the state machine the +address increment value corresponding to special +opcode 255. +.P +.I +The motivation for +.Cf DW_LNS_const_add_pc +is this: when the statement program needs +to advance the address by a small amount, it can use a single special +opcode, which occupies a single byte. When it needs to advance the +address by up to twice the range of the last special opcode, it can use +.Cf DW_LNS_const_add_pc +followed by a special opcode, for a total of two bytes. +Only if it needs to advance the address by more than twice that range +will it need to use both +.Cf DW_LNS_advance_pc +and a special opcode, requiring three or more bytes. +.R +.LI +.Cf DW_LNS_fixed_advance_pc +.br +Takes a single uhalf operand. Add to the +.Cf address +register of the state machine the value of the (unencoded) operand. +This is the only extended opcode that takes an argument that is not +a variable length number. +.P +.I +The motivation for +.Cf DW_LNS_fixed_advance_pc +is this: existing assemblers cannot emit +.Cf DW_LNS_advance_pc +or special opcodes because they cannot encode LEB128 numbers +or judge when the computation of a special opcode overflows and requires +the use of +.Cf DW_LNS_advance_pc . +Such assemblers, however, can use +.Cf DW_LNS_fixed_advance_pc +instead, sacrificing compression. +.R +.LE +.H 4 "Extended Opcodes" +.IX line number information, extended opcodes +There are three extended opcodes currently defined. The first byte +following the length field of the encoding for each contains a sub-opcode. +.AL +.LI +\f(CWDW_LNE_end_sequence\fP +.br +Set the +.Cf end_sequence +register of the state machine +to ``true'' and append a row to the matrix using the +current values of the state-machine registers. Then +reset the registers to the initial values specified +above. +.P +Every statement program sequence must end with a +.Cf DW_LNE_end_sequence +instruction which creates a +row whose address is that of the byte after the last target machine instruction +of the sequence. +.LI +\f(CWDW_LNE_set_address\fP +.br +Takes a single relocatable address as an operand. The size of the +operand is the size appropriate to hold an address on the target machine. +Set the +.Cf address +register to the value given by the +relocatable address. +.P +.I +All of the other statement program opcodes that affect the +.Cf address +register add a delta to it. +This instruction stores a relocatable value into it instead. +.R +.LI +\f(CWDW_LNE_define_file\fP +.br +.IX source, files +Takes 4 arguments. The first is a null terminated string containing a +source file name. The second is an +unsigned LEB128 number representing the directory index of the +directory in which the file was found. +The third is an unsigned LEB128 number representing +the time of last modification of the file. The fourth is an unsigned +LEB128 number representing the length in bytes of the file. +The time and length fields may contain LEB128(0) if the information is +not available. +.P +The directory index represents an entry in the +.Cf include_directories +section of the statement program prologue. +The index is LEB128(0) if the file was found in +the current directory of the compilation, LEB128(1) if it was +found in the first directory in the +.Cf include_directories +section, and so on. The directory index is ignored for file names +that represent full path names. +.P +The files are numbered, starting at 1, +in the order in which they appear; the names in the prologue +come before names defined by the +.Cf DW_LNE_define_file +instruction. +These numbers are used in the the +.Cf file +register of the state machine. +.LE +.P +.I +Appendix 3 gives some sample statement programs. +.R +.H 2 "Macro Information" +.I +.IX macro information +.IX pre-processor +.IX C %c +.IX C++ %caa +Some languages, such as C and C++, provide a way to replace text +in the source program with macros defined either in the source +file itself, or in another file included by the source file. +Because these macros are not themselves defined in the target +language, it is difficult to represent their definitions +using the standard language constructs of DWARF. The debugging +information therefore reflects the state of the source after +the macro definition has been expanded, rather than as the +programmer wrote it. +The macro information table provides a way of preserving the original +source in the debugging information. +.R +.P +As described in section 3.1, the macro information for a given +compilation unit is represented in the +.Cf .debug_macinfo +.IX \f(CW.debug_macinfo\fP %debugam +section of an object file. The macro information for each compilation +unit is represented as a series of ``macinfo'' entries. Each +macinfo entry consists of a ``type code'' and up to two additional +operands. The series of entries for a given compilation unit +ends with an entry containing a type code of 0. +.H 3 "Macinfo Types" +The valid macinfo types are as follows: +.VL 30 +.LI \f(CWDW_MACINFO_define\fP +A macro definition. +.LI \f(CWDW_MACINFO_undef\fP +A macro un-definition. +.LI \f(CWDW_MACINFO_start_file\fP +The start of a new source file inclusion. +.LI \f(CWDW_MACINFO_end_file\fP +The end of the current source file inclusion. +.LI \f(CWDW_MACINFO_vendor_ext\fP +Vendor specific macro information directives that do not fit +into one of the standard categories. +.LE +.H 4 "Define and Undefine Entries" +.IX macro information, define and undefine entries +All +.Cf DW_MACINFO_define +and +.Cf DW_MACINFO_undef +entries have two operands. +The first operand encodes the line number of the source line +.IX source, lines +on which the relevant defining or undefining +pre-processor directives appeared. +.P +The second operand consists of a null-terminated character string. +In the case of a +.Cf DW_MACINFO_undef +entry, the value of this +string will be simply the name of the pre-processor +symbol which was undefined at the indicated source line. +.P +In the case of a +.Cf DW_MACINFO_define +entry, the value of this +string will be the name of the pre-processor symbol +that was defined at the indicated source line, +followed immediately by the macro formal parameter +list including the surrounding parentheses (in the +case of a function-like macro) followed by the +definition string for the macro. If there is no +formal parameter list, then the name of the defined +macro is followed directly by its definition string. +.P +In the case of a function-like macro definition, no +whitespace characters should appear between the +name of the defined macro and the following left +parenthesis. Also, no whitespace characters should +appear between successive formal parameters in the +formal parameter list. (Successive formal parameters +should, however, be separated by commas.) Also, exactly +one space character +should separate the right parenthesis which terminates +the formal parameter list and the following definition +string. +.P +In the case of a ``normal'' (i.e. non-function-like) +macro definition, exactly one space character +should separate the name of the defined macro from the following definition +text. +.H 4 "Start File Entries" +.IX macro information, start file entries +Each +.Cf DW_MACINFO_start_file +entry also has two operands. The first operand +encodes the line number of the +source line on which the inclusion pre-processor +directive occurred. +.P +.IX source, files +The second operand encodes a +source file name index. This index corresponds to a file +number in the statement information table for the relevant +compilation unit. This index +indicates (indirectly) the name of the file +which is being included by the inclusion directive on +the indicated source line. +.H 4 "End File Entries" +.IX macro information, end file entries +A +.Cf DW_MACINFO_end_file +entry has no operands. The presence of the entry marks the end of +the current source file inclusion. +.H 4 "Vendor Extension Entries" +.IX macro information, vendor extensions +.IX vendor extensions +A +.Cf DW_MACINFO_vendor_ext +entry has two operands. +The first is a constant. The second is a null-terminated +character string. +The meaning and/or significance of these operands is +intentionally left undefined by this specification. +.P +A consumer must be able to totally ignore all +.Cf DW_MACINFO_vendor_ext +entries that it does not understand. +.H 3 "Base Source Entries" +.IX macro information, base source entries +In addition to producing a matched pair of +.Cf DW_MACINFO_start_file +and +.Cf DW_MACINFO_end_file +entries for +each inclusion directive actually processed during +compilation, a producer should generate such a matched +pair also for the ``base'' source file submitted to the +compiler for compilation. If the base source file +.IX source, files +for a compilation is submitted to the compiler via +some means other than via a named disk file (e.g. via +the standard input \fIstream\fP on a UNIX system) then the +compiler should still produce this matched pair of +.Cf DW_MACINFO_start_file +and +.Cf DW_MACINFO_end_file +entries for +the base source file, however, the file name indicated +(indirectly) by the +.Cf DW_MACINFO_start_file +entry of the +pair should reference a statement information file name entry consisting +of a null string. +.H 3 "Macinfo Entries for Command Line Options" +.IX macro information, command line options +In addition to producing +.Cf DW_MACINFO_define +and +.Cf DW_MACINFO_undef +entries for each of the define and +undefine directives processed during compilation, the +DWARF producer should generate a +.Cf DW_MACINFO_define +or +.Cf DW_MACINFO_undef +entry for each pre-processor symbol +which is defined or undefined by some +means other than via a define or undefine directive +within the compiled source text. In particular, +pre-processor symbol definitions and un-definitions +which occur as a result of command line options +(when invoking the compiler) should be represented by +their own +.Cf DW_MACINFO_define +and +.Cf DW_MACINFO_undef +entries. +.P +All such +.Cf DW_MACINFO_define +and +.Cf DW_MACINFO_undef +entries representing compilation options should appear +before the first +.Cf DW_MACINFO_start_file +entry for that compilation unit and should encode the value +0 in their line number operands. +.H 3 " General Rules and Restrictions" +.IX line number information, general rules +All macinfo entries within a +.Cf .debug_macinfo +section for a given compilation unit should appear in the same order +in which the directives were processed by the compiler. +.P +All macinfo entries representing command line options +should appear in the same order as the relevant command +line options were given to the compiler. In the case +where the compiler itself implicitly supplies one or +more macro definitions or un-definitions in addition +to those which may be specified on the command line, +macinfo entries should also be produced for these +implicit definitions and un-definitions, and +these entries should also appear in the proper order +relative to each other and to any definitions or +undefinitions given explicitly by the user on the +command line. +.H 2 "Call Frame Information" +.IX call frame information +.IX activations +.I +Debuggers often need to be able to view and modify the state of any +subroutine activation that is on the call stack. An activation +consists of: +.BL +.LI +A code location that is within the subroutine. This location is +either the place where the program stopped when the debugger got +control (e.g. a breakpoint), or is a place where a subroutine +made a call or was interrupted by an asynchronous event (e.g. a +signal). +.LI +An area of memory that is allocated on a stack called a ``call +frame.'' The call frame is identified by an address on the +stack. We refer to this address as the Canonical Frame Address or CFA. +.LI +A set of registers that are in use by the subroutine at the code +location. +.LE +.P +Typically, a set of registers are designated to be preserved across a +call. If a callee wishes to use such a register, it saves the value +that the register had at entry time in its call frame and restores it +on exit. The code that allocates space on the call frame stack and +performs the save operation is called the subroutine's prologue, and the +code that performs the restore operation and deallocates the frame is +called its epilogue. Typically, the prologue code is physically at the +beginning of a subroutine and the epilogue code is at the end. +.P +To be able to view or modify an activation that is not on the top of +the call frame stack, the debugger must ``virtually unwind'' the stack of +activations until it finds the activation of interest. +A debugger unwinds a +stack in steps. Starting with the current activation it restores any +registers that were preserved by the current activation and computes the +predecessor's CFA and code location. This has the logical effect of +returning from the current subroutine to its predecessor. We say that +the debugger virtually unwinds the stack because it preserves enough +information to be able to ``rewind'' the stack back to the state it was +in before it attempted to unwind it. +.P +The unwinding operation needs to know where registers are saved and how +to compute the predecessor's CFA and code location. When considering +an architecture-independent way of encoding this information one has to +consider a number of special things. +.BL +.LI +Prologue and epilogue code is not always in distinct blocks at the +beginning and end of a subroutine. It is common to duplicate the +epilogue code at the site of each return from the code. Sometimes +a compiler breaks up the register save/unsave operations and moves +them into the body of the subroutine to just where they are needed. +.LI +Compilers use different ways to manage the call frame. Sometimes +they use a frame pointer register, sometimes not. +.LI +The algorithm to compute the CFA changes as you progress through +the prologue and epilogue code. (By definition, the CFA value +does not change.) +.LI +Some subroutines have no call frame. +.LI +Sometimes a register is saved in another register that by +convention does not need to be saved. +.LI +Some architectures have special instructions that +perform some or all of the register management in one instruction, +leaving special information on the stack that indicates how +registers are saved. +.LI +Some architectures treat return address values +specially. For example, in one architecture, +the call instruction guarantees that the low order two +bits will be zero and the return instruction ignores those bits. +This leaves two bits of storage that are available to other uses +that must be treated specially. +.LE +.R +.H 3 "Structure of Call Frame Information" +.IX call frame information, structure +DWARF supports virtual unwinding by defining an architecture independent +basis for recording how procedures save and restore registers throughout +their lifetimes. This basis must be augmented on some machines with +specific information that is defined by either an architecture specific +ABI authoring committee, a hardware vendor, or a compiler producer. +.IX ABI +.IX vendor extensions +The body defining a specific augmentation is referred to +below as the ``augmenter.'' +.P +Abstractly, this mechanism describes a very large table that has the +following structure: +.TS +center; +l l l l l l +l s s s s s. +LOC CFA R0 R1 ... RN +L0 +L1 +\... +LN +.TE +.P +The first column indicates an address for every location that contains +code in a program. (In shared objects, this is an object-relative +offset.) The remaining columns contain virtual unwinding rules that are +associated with the indicated location. The first column of the rules +defines the CFA rule which is a register and a signed offset that are +added together to compute the CFA value. +.P +The remaining columns are labeled by register number. This includes +some registers that have special designation on some architectures such +as the PC and the stack pointer register. (The actual mapping of +registers for a particular architecture is performed by the augmenter.) +The register columns contain rules that describe +whether a given register has been saved and the rule to find +the value for the register in the previous frame. +.P +The register rules are: +.IX call frame information, register rules +.VL 20 +.LI "undefined" +A register that has this rule has no value in the +previous frame. (By convention, it is not preserved by a callee.) +.LI "same value" +This register has not been modified from the +previous frame. (By convention, it is preserved by the callee, +but the callee has not modified it.) +.LI "offset(N)" +The previous value of this register is saved at the address CFA+N where +CFA is the current CFA value and N is a signed offset. +.LI "register(R)" +The previous value of this register is stored in +another register numbered R. +.LI "architectural" +The rule is defined externally to this specification by the augmenter. +.LE +.P +.I +This table would be extremely large if actually constructed as +described. Most of the entries at any point in the table are identical +to the ones above them. The whole table can be represented quite +compactly by recording just the differences starting at the beginning +address of each subroutine in the program. +.R +.P +The virtual unwind information is encoded in a self-contained section +called +.Cf .debug_frame . +.IX \f(CW.debug_frame\fP %debugaf +Entries in a +.Cf .debug_frame +section are aligned on +.IX call frame information, Common Information Entry +an addressing unit boundary and come in two forms: A Common Information +Entry (CIE) and a Frame Description Entry (FDE). +Sizes of data objects used in the encoding of the +.Cf .debug_frame +section are described in terms of the same data definitions +used for the line number information (see section 6.2.1). +.P +A Common Information Entry holds information that is shared among many +Frame Descriptors. There is at least one CIE in every non-empty +.Cf .debug_frame +section. A CIE contains the following fields, in order: +.AL +.LI +\f(CWlength\fP +.br +A uword constant that gives the number of bytes of the CIE +structure, not including the length field, itself +(length mod == 0). +.LI +\f(CWCIE_id\fP +.br +A uword constant that is used to distinguish CIEs +from FDEs. +.LI +\f(CWversion\fP +.br +A ubyte version number. This number is specific to the call frame +information and is independent of the DWARF version number. +.LI +\f(CWaugmentation\fP +.br +A null terminated string that identifies the +augmentation to this CIE or to the FDEs that use +it. If a reader encounters an augmentation string that is +unexpected, then only the following fields can be read: +CIE: +.Cf length , +.Cf CIE_id , +.Cf version , +.Cf augmentation ; +FDE: +.Cf length , +.Cf CIE_pointer , +.Cf initial_location , +.Cf address_range . +If there is no augmentation, this value is a zero byte. +.LI +\f(CWcode_alignment_factor\fP +.br +An unsigned LEB128 constant that is factored out +of all advance location instructions (see below). +.LI +\f(CWdata_alignment_factor\fP +.br +A signed LEB128 constant that is factored out +of all offset instructions (see below.) +.LI +\f(CWreturn_address_register\fP +.br +A ubyte constant that indicates +which column in the rule table represents the return address +of the function. Note that this column might not correspond +to an actual machine register. +.LI +\f(CWinitial_instructions\fP +.br +A sequence of rules that are interpreted to +create the initial setting of each column in the table. +.LI +\f(CWpadding\fP +.br +Enough +.Cf DW_CFA_nop +instructions to make the size of this entry +match the +.Cf length +value above. +.LE +.P +An FDE contains the following fields, in order: +.IX call frame information, Frame Description Entry +.AL +.LI +\f(CWlength\fP +.br +A uword constant that gives the number of bytes of the header +and instruction stream for this function (not including the length +field itself) (length mod == 0). +.LI +\f(CWCIE_pointer\fP +.br +A uword constant offset into the +.Cf .debug_frame +section that denotes the CIE that is associated with this FDE. +.LI +\f(CWinitial_location\fP +An addressing-unit sized constant indicating +the address of the first location associated with this table entry. +.LI +\f(CWaddress_range\fP +.br +An addressing unit sized constant indicating the +number of bytes of program instructions described by this entry. +.LI +\f(CWinstructions\fP +.br +A sequence of table defining instructions that are +described below. +.LE +.H 3 "Call Frame Instructions" +.IX call frame information, instructions +Each call frame instruction is defined to +take 0 or more operands. Some of the operands may be +encoded as part of the opcode (see section 7.23). +The instructions are as follows: +.AL +.LI +.Cf DW_CFA_advance_loc +takes a single argument that represents a constant delta. +The required action is to +create a new table row with a location value that +is computed by taking the current entry's location value and +adding (delta * \f(CWcode_alignment_factor\fP). All other values in the +new row are initially identical to the current row. +.LI +.Cf DW_CFA_offset +takes two arguments: +an unsigned LEB128 constant representing a factored offset +and a register number. The required action is +to change the rule for the register indicated by the register +number to be an offset(N) rule with a value of +(N = factored offset * \f(CWdata_alignment_factor\fP). +.LI +.Cf DW_CFA_restore +takes a single argument that represents a register number. +The required action is +to change the rule for the indicated register +to the rule assigned it by the \f(CWinitial_instructions\fP in the CIE. +.LI +.Cf DW_CFA_set_loc +takes a single argument that represents an address. +The required action is to create a new table row +using the specified address as the location. +All other values in the +new row are initially identical to the current row. +The new location value should always be greater than the current +one. +.LI +.Cf DW_CFA_advance_loc1 +takes a single ubyte argument that represents a constant delta. +This instruction is identical to +.Cf DW_CFA_advance_loc +except for the encoding and size of the delta argument. +.LI +.Cf DW_CFA_advance_loc2 +takes a single uhalf argument that represents a constant delta. +This instruction is identical to +.Cf DW_CFA_advance_loc +except for the encoding and size of the delta argument. +.LI +.Cf DW_CFA_advance_loc4 +takes a single uword argument that represents a constant delta. +This instruction is identical to +.Cf DW_CFA_advance_loc +except for the encoding and size of the delta argument. +.LI +.Cf DW_CFA_offset_extended +takes two unsigned LEB128 arguments representing a register number +and a factored offset. +This instruction is identical to +.Cf DW_CFA_offset +except for the encoding and size of the register argument. +.LI +.Cf DW_CFA_restore_extended +takes a single unsigned LEB128 argument that represents a register number. +This instruction is identical to +.Cf DW_CFA_restore +except for the encoding and size of the register argument. +.LI +.Cf DW_CFA_undefined +takes a single unsigned LEB128 argument that represents a register number. +The required action is to set the rule for the specified register +to ``undefined.'' +.LI +.Cf DW_CFA_same_value +takes a single unsigned LEB128 argument that represents a register number. +The required action is to set the rule for the specified register +to ``same value.'' +.LI +.Cf DW_CFA_register +takes two unsigned LEB128 arguments representing register numbers. +The required action is to set the rule for the first register +to be the second register. +.LI +\f(CWDW_CFA_remember_state\fP +.LI +\f(CWDW_CFA_restore_state\fP +.br +These instructions define a stack of information. Encountering the +.Cf DW_CFA_remember_state +instruction means to save the rules for every register +on the current row on the stack. Encountering the +.Cf DW_CFA_restore_state +instruction means to pop the set of rules +off the stack and place them in the current row. +.I +(This +operation is useful for compilers that move epilogue +code into the body of a function.) +.R +.LI +.Cf DW_CFA_def_cfa +takes two unsigned LEB128 arguments representing a +register number and an offset. +The required action is to define the current CFA rule +to use the provided register and offset. +.LI +.Cf DW_CFA_def_cfa_register +takes a single unsigned LEB128 argument representing a register +number. The required action is to define the current CFA +rule to use the provided register (but to keep the old offset). +.LI +.Cf DW_CFA_def_cfa_offset +takes a single unsigned LEB128 argument representing an offset. +The required action is to define the current CFA +rule to use the provided offset (but to keep the old register). +.LI +.Cf DW_CFA_nop +has no arguments and no required actions. It is used as padding +to make the FDE an appropriate size. +.LE +.H 3 "Call Frame Instruction Usage" +.IX call frame information, usage +.I +To determine the virtual unwind rule set for a given location (L1), one +searches through the FDE headers looking at the +.Cf initial_location +and +.Cf address_range +values to see if L1 is contained in the FDE. If so, then: +.AL +.LI +Initialize a register set by reading the +.Cf initial_instructions +field of the associated CIE. +.LI +Read and process the FDE's instruction sequence until a +.Cf DW_CFA_advance_loc , +.Cf DW_CFA_set_loc , +or the end of the instruction stream is +encountered. +.LI +If a +.Cf DW_CFA_advance_loc +or +.Cf DW_CFA_set_loc +instruction was encountered, then +compute a new location value (L2). If L1 >= L2 then process the +instruction and go back to step 2. +.LI +The end of the instruction stream can be thought of as a +.br +\f(CWDW_CFA_set_loc( initial_location + address_range )\fP +.br +instruction. +Unless the FDE is ill-formed, L1 should be less than L2 at this point. +.LE +.P +The rules in the register set now apply to location L1. +.P +For an example, see Appendix 5. +.R +.OP +.H 1 "DATA REPRESENTATION" +This section describes the binary representation of the debugging +information entry itself, of the +attribute types and of other fundamental elements described above. +.H 2 "Vendor Extensibility" +.IX vendor extensions +To reserve a portion of the DWARF name space and ranges of +enumeration values for use for vendor specific extensions, +.IX tags +.IX types, base +.IX base types +.IX locations, expressions +.IX calling conventions +.IX call frame information +special labels are reserved for tag names, attribute names, +base type encodings, location operations, language names, +calling conventions and call frame instructions. +The labels denoting the beginning and end of the reserved value +range for vendor specific extensions consist of the appropriate prefix ( +.Cf DW_TAG , +.Cf DW_AT , +.Cf DW_ATE , +.Cf DW_OP , +.Cf DW_LANG , +.CF DW_CC +or +.Cf DW_CFA +respectively) followed by +.Cf _lo_user +or +.Cf _hi_user . +For example, for entry tags, the special labels are +.Cf DW_TAG_lo_user +and +.Cf DW_TAG_hi_user . +Values in the range between \fIprefix\fP\f(CW_lo_user\fP and +\fIprefix\fP\f(CW_hi_user\fP +inclusive, are reserved for vendor specific extensions. +Vendors may use values in this range without +conflicting with current or future system-defined values. +All other values are reserved for use by the system. +.P +Vendor defined tags, attributes, base type encodings, location atoms, +language names, calling conventions and call frame instructions, +conventionally use the form +\fIprefix\f(CW_\fIvendor_id\f(CW_\fIname\fR, where \fIvendor_id\fP is some +identifying character sequence chosen so as to avoid conflicts with other +vendors. +.P +.IX compatibility +To ensure that extensions added by one vendor may be safely ignored +by consumers that do not understand those extensions, +the following rules should be followed: +.AL +.LI +New attributes should be added in such a way that a debugger may recognize +the format of a new attribute value without knowing the content of that +attribute value. +.LI +The semantics of any new attributes should not alter the semantics of +previously existing attributes. +.LI +The semantics of any new tags +should not conflict with the semantics of previously existing tags. +.LE +.H 2 "Reserved Error Values" +.IX error values +As a convenience for consumers of DWARF information, +the value 0 is reserved in the encodings for attribute names, attribute +forms, base type encodings, location operations, languages, +statement program opcodes, macro information entries and tag names +to represent an error condition or unknown value. DWARF does +not specify names for these reserved values, since they do not +represent valid encodings for the given type and should not appear +in DWARF debugging information. +.H 2 "Executable Objects and Shared Objects" +The relocated addresses in the debugging information for an executable +object are virtual addresses and the relocated addresses in the +debugging information for a shared object are offsets relative to +the start of the lowest segment used by that shared object. +.P +.I +This requirement makes the debugging information for shared objects +position independent. +Virtual addresses in a shared object may be calculated by adding the +offset to the base address at which the object was attached. +This offset is available in the run-time linker's data structures. +.H 2 "File Constraints" +All debugging information entries in a relocatable object file, +executable object or shared +object are required to be physically contiguous. +.H 2 "Format of Debugging Information" +.IX Version 2 +For each compilation unit compiled with a DWARF Version 2 producer, +.IX compilation units +.IX compilation units, header +a contribution is made to the +.Cf .debug_info +.IX \f(CW.debug_info\fP %debugai +section of the object file. Each such contribution consists of +a compilation unit header followed by a series of debugging information +entries. Unlike the information encoding for DWARF Version 1, Version 2 +.IX Version 1 +debugging information entries do not themselves contain the debugging +information entry tag or the attribute name and form encodings for +each attribute. Instead, each debugging information entry begins with +a code that represents an entry in a separate abbreviations table. +This code is followed directly by a series of attribute values. +The appropriate entry in the abbreviations table guides the interpretation +of the information contained directly in the +.Cf .debug_info +section. Each compilation unit is associated with a particular +abbreviation table, but multiple compilation units may share +the same table. +.IX abbreviations table +.I +.P +This encoding was based on the observation that typical DWARF producers +produce a very limited number of different types of debugging information +entries. By extracting the common information from those entries +into a separate table, we are able to compress the generated information. +.R +.H 3 "Compilation Unit Header" +.IX compilation units, header +The header for the series of debugging information entries contributed +by a single compilation unit consists of the following information: +.AL +.LI +A 4-byte unsigned integer representing the length of the +.Cf .debug_info +contribution for that compilation unit, not including the length field itself. +.LI +A 2-byte unsigned integer representing the version of the DWARF information +for that compilation unit. For DWARF Version 2, the value in this field is 2. +.IX Version 2 +.LI +A 4-byte unsigned offset into the +.Cf .debug_abbrev +.IX \f(CW.debug_abbrev\fP %debugaab +section. This offset associates the compilation unit with a particular +set of debugging information entry abbreviations. +.LI +.IX segmented address space +.IX address space, segmented +.IX addresses, size of +A 1-byte unsigned integer representing the size in bytes of an address +on the target architecture. If the system uses segmented addressing, +this value represents the size of the offset portion of an address. +.IX addresses, offset portion +.LE +.P +.I +The compilation unit header does not replace the +.Cf DW_TAG_compile_unit +debugging information entry. It is additional information that +is represented outside the standard DWARF tag/attributes format. +.R +.H 3 "Debugging Information Entry" +Each debugging information entry begins with an unsigned LEB128 +.IX debugging information entries +number containing the abbreviation code for the entry. +This code represents an entry within the abbreviation table associated +with the compilation unit containing this entry. The abbreviation +.IX abbreviations table +code is followed by a series of attribute values. +.IX attributes, values +.P +On some architectures, there are alignment constraints on section boundaries. +To make it easier to pad debugging information sections to satisfy +such constraints, the abbreviation code 0 is reserved. Debugging +information entries consisting of only the 0 abbreviation code are considered +null entries. +.IX debugging information entries, null entries +.H 3 "Abbreviation Tables" +.IX abbreviations table +The abbreviation tables for all compilation units are contained in +a separate object file section called +.Cf .debug_abbrev . +.IX \f(CW.debug_abbrev\fP %debugaab +As mentioned before, multiple compilation units may share the same +abbreviation table. +.P +The abbreviation table for a single compilation +unit consists of a series of abbreviation declarations. +Each declaration specifies the tag and attributes for a particular +.IX tags +.IX attributes +form of debugging information entry. Each declaration begins with +an unsigned LEB128 number representing the abbreviation code itself. +It is this code that appears at the beginning of a debugging information +entry in the +.Cf .debug_info +section. As described above, the abbreviation code 0 is reserved for null +debugging information entries. +The abbreviation code is followed by another unsigned LEB128 +number that encodes the entry's tag. +.IX tags +.nr aX \n(Fg+1 +.nr bX \n(Fg+2 +The encodings for the tag names are given in Figures \n(aX +and \n(bX. +.DF +.TS +box center; +l l +lf(CW) lf(CW) +. +Tag name Value +_ +DW_TAG_array_type 0x01 +DW_TAG_class_type 0x02 +DW_TAG_entry_point 0x03 +DW_TAG_enumeration_type 0x04 +DW_TAG_formal_parameter 0x05 +DW_TAG_imported_declaration 0x08 +DW_TAG_label 0x0a +DW_TAG_lexical_block 0x0b +DW_TAG_member 0x0d +DW_TAG_pointer_type 0x0f +DW_TAG_reference_type 0x10 +DW_TAG_compile_unit 0x11 +DW_TAG_string_type 0x12 +DW_TAG_structure_type 0x13 +DW_TAG_subroutine_type 0x15 +DW_TAG_typedef 0x16 +DW_TAG_union_type 0x17 +DW_TAG_unspecified_parameters 0x18 +DW_TAG_variant 0x19 +DW_TAG_common_block 0x1a +DW_TAG_common_inclusion 0x1b +DW_TAG_inheritance 0x1c +DW_TAG_inlined_subroutine 0x1d +DW_TAG_module 0x1e +DW_TAG_ptr_to_member_type 0x1f +DW_TAG_set_type 0x20 +DW_TAG_subrange_type 0x21 +DW_TAG_with_stmt 0x22 +DW_TAG_access_declaration 0x23 +DW_TAG_base_type 0x24 +DW_TAG_catch_block 0x25 +DW_TAG_const_type 0x26 +DW_TAG_constant 0x27 +DW_TAG_enumerator 0x28 +DW_TAG_file_type 0x29 +.TE +.FG "Tag encodings (part 1)" +.DE +.DF +.TS +box center; +l l +lf(CW) lf(CW) +. +Tag name Value +_ +DW_TAG_friend 0x2a +DW_TAG_namelist 0x2b +DW_TAG_namelist_item 0x2c +DW_TAG_packed_type 0x2d +DW_TAG_subprogram 0x2e +DW_TAG_template_type_param 0x2f +DW_TAG_template_value_param 0x30 +DW_TAG_thrown_type 0x31 +DW_TAG_try_block 0x32 +DW_TAG_variant_part 0x33 +DW_TAG_variable 0x34 +DW_TAG_volatile_type 0x35 +DW_TAG_lo_user 0x4080 +DW_TAG_hi_user 0xffff +.TE +.FG "Tag encodings (part 2)" +.DE +.P +Following the tag encoding is a 1-byte value that determines +whether a debugging information entry using this abbreviation +has child entries or not. If the value is +.Cf DW_CHILDREN_yes , +the next physically succeeding entry of any debugging information +entry using this abbreviation is the first child of the prior entry. +If the 1-byte value following the abbreviation's tag encoding +is +.Cf DW_CHILDREN_no , +the next physically succeeding entry of any debugging information entry +using this abbreviation is a sibling of the prior entry. (Either +the first child or sibling entries may be null entries). +.IX debugging information entries, siblings +.IX debugging information entries, child entries +.IX debugging information entries, null entries +.nr aX \n(Fg+1 +The encodings for the child determination byte are given in Figure \n(aX. +(As mentioned in section 2.3, each chain of sibling entries is +terminated by a null entry). +.IX debugging information entries, null entries +.DF +.TS +box center; +l l +lf(CW) lf(CW) +. +Child determination name Value +_ +DW_CHILDREN_no 0 +DW_CHILDREN_yes 1 +.TE +.FG "Child determination encodings" +.DE +.P +Finally, the child encoding is followed by a series of attribute specifications. +.IX attributes +Each attribute specification consists of two parts. The first part +is an unsigned LEB128 number representing the attribute's name. +.IX attributes, names +The second part is an unsigned LEB128 number representing the +attribute's form. The series of attribute specifications ends +.IX attributes, forms +with an entry containing 0 for the name and 0 for the form. +.P +The attribute form +.Cf DW_FORM_indirect +is a special case. For attributes with this form, the attribute value +itself in the +.Cf .debug_info +section begins with an unsigned LEB128 number that represents its form. +This allows producers to choose forms for particular attributes dynamically, +without having to add a new entry to the abbreviation table. +.P +The abbreviations for a given compilation unit end with an entry +consisting of a 0 byte for the abbreviation code. +.I +.P +See Appendix 2 for a depiction of the organization +of the debugging information. +.R +.H 3 "Attribute Encodings" +.nr aX \n(Fg+1 +.nr bX \n(Fg+2 +The encodings for the attribute names are given in Figures \n(aX +and \n(bX. +.DF +.TS +box center; +l l l +lf(CW) lf(CW) l +. +Attribute name Value Classes +_ +DW_AT_sibling 0x01 reference +DW_AT_location 0x02 block, constant +DW_AT_name 0x03 string +DW_AT_ordering 0x09 constant +DW_AT_byte_size 0x0b constant +DW_AT_bit_offset 0x0c constant +DW_AT_bit_size 0x0d constant +DW_AT_stmt_list 0x10 constant +DW_AT_low_pc 0x11 address +DW_AT_high_pc 0x12 address +DW_AT_language 0x13 constant +DW_AT_discr 0x15 reference +DW_AT_discr_value 0x16 constant +DW_AT_visibility 0x17 constant +DW_AT_import 0x18 reference +DW_AT_string_length 0x19 block, constant +DW_AT_common_reference 0x1a reference +DW_AT_comp_dir 0x1b string +DW_AT_const_value 0x1c string, constant, block +DW_AT_containing_type 0x1d reference +DW_AT_default_value 0x1e reference +DW_AT_inline 0x20 constant +DW_AT_is_optional 0x21 flag +DW_AT_lower_bound 0x22 constant, reference +DW_AT_producer 0x25 string +DW_AT_prototyped 0x27 flag +DW_AT_return_addr 0x2a block, constant +DW_AT_start_scope 0x2c constant +DW_AT_stride_size 0x2e constant +DW_AT_upper_bound 0x2f constant, reference +.TE +.FG "Attribute encodings, part 1" +.DE +.DF +.TS +box center; +l l l +lf(CW) lf(CW) l +. +Attribute name Value Classes +_ +DW_AT_abstract_origin 0x31 reference +DW_AT_accessibility 0x32 constant +DW_AT_address_class 0x33 constant +DW_AT_artificial 0x34 flag +DW_AT_base_types 0x35 reference +DW_AT_calling_convention 0x36 constant +DW_AT_count 0x37 constant, reference +DW_AT_data_member_location 0x38 block, reference +DW_AT_decl_column 0x39 constant +DW_AT_decl_file 0x3a constant +DW_AT_decl_line 0x3b constant +DW_AT_declaration 0x3c flag +DW_AT_discr_list 0x3d block +DW_AT_encoding 0x3e constant +DW_AT_external 0x3f flag +DW_AT_frame_base 0x40 block, constant +DW_AT_friend 0x41 reference +DW_AT_identifier_case 0x42 constant +DW_AT_macro_info 0x43 constant +DW_AT_namelist_item 0x44 block +DW_AT_priority 0x45 reference +DW_AT_segment 0x46 block, constant +DW_AT_specification 0x47 reference +DW_AT_static_link 0x48 block, constant +DW_AT_type 0x49 reference +DW_AT_use_location 0x4a block, constant +DW_AT_variable_parameter 0x4b flag +DW_AT_virtuality 0x4c constant +DW_AT_vtable_elem_location 0x4d block, reference +DW_AT_lo_user 0x2000 \(em +DW_AT_hi_user 0x3fff \(em +.TE +.FG "Attribute encodings, part 2" +.DE +.P +.IX attributes, forms +The attribute form governs how the value of the attribute is encoded. +The possible forms may belong to one of the following +form classes: +.VL 18 +.LI address +.IX attributes, addresses +Represented as an object of appropriate size to hold an +address on the target machine (\f(CWDW_FORM_addr\fP). +This address is relocatable in +a relocatable object file and is relocated in an +executable file or shared object. +.LI "block" +.IX attributes, blocks +Blocks come in four forms. The first consists of a 1-byte length +followed by 0 to 255 contiguous information bytes (\f(CWDW_FORM_block1\fP). +The second consists of a 2-byte length +followed by 0 to 65,535 contiguous information bytes (\f(CWDW_FORM_block2\fP). +The third consists of a 4-byte length +followed by 0 to 4,294,967,295 contiguous information bytes (\f(CWDW_FORM_block4\fP). +The fourth consists of an unsigned LEB128 length followed by the number +of bytes specified by the length (\f(CWDW_FORM_block\fP). +In all forms, the length is the number of information bytes that follow. +The information bytes may contain any mixture of relocated (or +relocatable) addresses, references to other debugging information entries or +data bytes. +.LI "constant" +.IX attributes, constants +There are six forms of constants: +one, two, four and eight byte values (respectively, +.Cf DW_FORM_data1 , +.Cf DW_FORM_data2 , +.Cf DW_FORM_data4 , +and +.Cf DW_FORM_data8 ). +.IX variable length data +.IX LEB128 +There are also variable length constant data forms encoded +using LEB128 numbers (see below). Both signed (\f(CWDW_FORM_sdata\fP) +and unsigned (\f(CWDW_FORM_udata\fP) variable length constants are available. +.LI flag +.IX attributes, flags +A flag is represented as a single byte of data (\f(CWDW_FORM_flag\fP). +If the flag has value zero, it indicates the absence of the attribute. +If the flag has a non-zero value, it indicates the presence of +the attribute. +.LI reference +.IX attributes, references +There are two types of reference. The first is an +offset relative to the first byte of the compilation unit header +for the compilation unit containing the reference. +The offset must refer to an entry within +that same compilation unit. There are five forms for this +type of reference: +one, two, four and eight byte offsets (respectively, +.Cf DW_FORM_ref1 , +.Cf DW_FORM_ref2 , +.Cf DW_FORM_ref4 , +and +.Cf DW_FORM_ref8 ). +There are is also an unsigned variable length offset encoded +using LEB128 numbers (\f(CWDW_FORM_ref_udata\fP). +.P +The second type of reference +is the address of any debugging information entry within +the same executable or shared object; it may refer to an entry +in a different compilation unit from the unit containing the +reference. This type of reference (\f(CWDW_FORM_ref_addr\fP) is the +size of an address on the target architecture; it is relocatable +in a relocatable object file and relocated in an executable file +or shared object. +.P +.I +The use of compilation unit relative references will reduce +the number of link-time relocations and so speed up linking. +.P +The use of address-type references allows for the commonization +of information, such as types, across compilation units. +.R +.LI string +.IX attributes, strings +A string is a sequence of contiguous non-null bytes followed by one null +byte. A string may be represented immediately in the debugging information +entry itself (\f(CWDW_FORM_string\fP), or may be represented as a 4-byte offset +into a string table contained in the +.Cf .debug_str +.IX \f(CW.debug_str\fP %debugas +.IX string table +section of the object file (\f(CWDW_FORM_strp\fP). +.LE +.P +.nr aX \n(Fg+1 +The form encodings are listed in Figure \n(aX. +.DF +.TS +box center; +l l l +lf(CW) lf(CW) l +. +Form name Value Class +_ +DW_FORM_addr 0x01 address +DW_FORM_block2 0x03 block +DW_FORM_block4 0x04 block +DW_FORM_data2 0x05 constant +DW_FORM_data4 0x06 constant +DW_FORM_data8 0x07 constant +DW_FORM_string 0x08 string +DW_FORM_block 0x09 block +DW_FORM_block1 0x0a block +DW_FORM_data1 0x0b constant +DW_FORM_flag 0x0c flag +DW_FORM_sdata 0x0d constant +DW_FORM_strp 0x0e string +DW_FORM_udata 0x0f constant +DW_FORM_ref_addr 0x10 reference +DW_FORM_ref1 0x11 reference +DW_FORM_ref2 0x12 reference +DW_FORM_ref4 0x13 reference +DW_FORM_ref8 0x14 reference +DW_FORM_ref_udata 0x15 reference +DW_FORM_indirect 0x16 (see section 7.5.3) +.TE +.FG "Attribute form encodings" +.DE +.H 2 "Variable Length Data" +.IX variable length data +.IX LEB128 +The special constant data forms +.Cf DW_FORM_sdata +and +.Cf DW_FORM_udata +are encoded using ``Little Endian Base 128'' (LEB128) +numbers. LEB128 is a scheme for encoding integers densely that +exploits the assumption that most integers are small in magnitude. +(This encoding is equally suitable whether the target machine +architecture represents data in big-endian or little-endian order. +It is ``little endian'' only in the sense that it avoids using space +to represent the ``big'' end of an unsigned integer, when the big +end is all zeroes or sign extension bits). +.P +.Cf DW_FORM_udata +(unsigned LEB128) numbers are encoded as follows: +start at the +low order end of an unsigned integer and chop it into 7-bit chunks. +Place each chunk into the low order 7 bits of a byte. Typically, +several of the high order bytes will be zero; discard them. Emit the +remaining bytes in a stream, starting with the low order byte; +set the high order bit on each byte except the last emitted byte. +The high bit of zero on the last byte indicates to the decoder +that it has encountered the last byte. +.P +The integer zero is a special case, consisting of a single zero byte. +.P +.I +.nr aX \n(Fg+1 +Figure \n(aX gives some examples of +.Cf DW_FORM_udata +numbers. The +.Cf 0x80 +in each case is the high order bit of the byte, indicating that +an additional byte follows: +.R +.DF +.TS +box center; +l l l +nf(CW) lf(CW) lf(CW) +. +Number First byte Second byte +_ +2 2 \(em +127 127 \(em +128 0+0x80 1 +129 1+0x80 1 +130 2+0x80 1 +12857 57+0x80 100 +.TE +.FG "Examples of unsigned LEB128 encodings" +.DE +.P +The encoding for +.Cf DW_FORM_sdata +(signed, 2s complement LEB128) numbers is similar, except that the +criterion for discarding high order bytes is not whether they are +zero, but whether they consist entirely of sign extension bits. +Consider the 32-bit integer +.Cf -2 . +The three high level bytes of the number are sign extension, thus LEB128 +would represent it as a single byte containing the low order 7 bits, +with the high order bit cleared to indicate the end of the byte +stream. Note that there is nothing within the LEB128 representation +that indicates whether an encoded number is signed or unsigned. +The decoder must know what type of number to expect. +.P +.I +.nr aX \n(Fg+1 +Figure \n(aX gives some examples of +.Cf DW_FORM_sdata +numbers. +.R +.P +.I +Appendix 4 gives algorithms for encoding and decoding these forms. +.R +.DF +.TS +box center; +l l l +nf(CW) lf(CW) lf(CW) +. +Number First byte Second byte +_ +2 2 \(em +-2 0x7e \(em +127 127+0x80 0 +-127 1+0x80 0x7f +128 0+0x80 1 +-128 0+0x80 0x7f +129 1+0x80 1 +-129 0x7f+0x80 0x7e +.TE +.FG "Examples of signed LEB128 encodings" +.DE +.H 2 "Location Descriptions" +.H 3 "Location Expressions" +.IX locations, descriptions +.IX locations, expressions +A location expression is stored in a block of contiguous bytes. +The bytes form a set of operations. +Each location operation has a 1-byte code +that identifies that operation. Operations can be followed +by one or more bytes of additional data. All operations in a +location expression are concatenated from left to right. +The encodings for the operations in a location expression +.IX locations, expressions +.nr aX \n(Fg+1 +.nr bX \n(Fg+2 +are described in Figures \n(aX and \n(bX. +.DS +.TS +center box; +l l l l +lf(CW) lf(CW) l l +. +Operation Code No. of Operands Notes +_ +DW_OP_addr 0x03 1 constant address (size target specific) +DW_OP_deref 0x06 0 +DW_OP_const1u 0x08 1 1-byte constant +DW_OP_const1s 0x09 1 1-byte constant +DW_OP_const2u 0x0a 1 2-byte constant +DW_OP_const2s 0x0b 1 2-byte constant +DW_OP_const4u 0x0c 1 4-byte constant +DW_OP_const4s 0x0d 1 4-byte constant +DW_OP_const8u 0x0e 1 8-byte constant +DW_OP_const8s 0x0f 1 8-byte constant +DW_OP_constu 0x10 1 ULEB128 constant +DW_OP_consts 0x11 1 SLEB128 constant +DW_OP_dup 0x12 0 +DW_OP_drop 0x13 0 +DW_OP_over 0x14 0 +DW_OP_pick 0x15 1 1-byte stack index +DW_OP_swap 0x16 0 +DW_OP_rot 0x17 0 +DW_OP_xderef 0x18 0 +DW_OP_abs 0x19 0 +DW_OP_and 0x1a 0 +DW_OP_div 0x1b 0 +DW_OP_minus 0x1c 0 +DW_OP_mod 0x1d 0 +DW_OP_mul 0x1e 0 +DW_OP_neg 0x1f 0 +DW_OP_not 0x20 0 +DW_OP_or 0x21 0 +DW_OP_plus 0x22 0 +DW_OP_plus_uconst 0x23 1 ULEB128 addend +DW_OP_shl 0x24 0 +DW_OP_shr 0x25 0 +DW_OP_shra 0x26 0 +.TE +.FG "Location operation encodings, part 1" +.DE +.DS +.TS +center box; +l l l l +lf(CW) lf(CW) l l +. +Operation Code No. of Operands Notes +_ +DW_OP_xor 0x27 0 +DW_OP_skip 0x2f 1 signed 2-byte constant +DW_OP_bra 0x28 1 signed 2-byte constant +DW_OP_eq 0x29 0 +DW_OP_ge 0x2a 0 +DW_OP_gt 0x2b 0 +DW_OP_le 0x2c 0 +DW_OP_lt 0x2d 0 +DW_OP_ne 0x2e 0 +DW_OP_lit0 0x30 0 literals 0..31 = (DW_OP_LIT0|literal) +DW_OP_lit1 0x31 0 +\.\.\. +DW_OP_lit31 0x4f 0 +DW_OP_reg0 0x50 0 reg 0..31 = (DW_OP_REG0|regnum) +DW_OP_reg1 0x51 0 +\.\.\. +DW_OP_reg31 0x6f 0 +DW_OP_breg0 0x70 1 SLEB128 offset +DW_OP_breg1 0x71 1 base reg 0..31 = (DW_OP_BREG0|regnum) +\.\.\. +DW_OP_breg31 0x8f 1 +DW_OP_regx 0x90 1 ULEB128 register +DW_OP_fbreg 0x91 1 SLEB128 offset +DW_OP_bregx 0x92 2 ULEB128 register followed by SLEB128 offset +DW_OP_piece 0x93 1 ULEB128 size of piece addressed +DW_OP_deref_size 0x94 1 1-byte size of data retrieved +DW_OP_xderef_size 0x95 1 1-byte size of data retrieved +DW_OP_nop 0x96 0 +DW_OP_lo_user 0xe0 +DW_OP_hi_user 0xff +.TE +.FG "Location operation encodings, part 2" +.DE +.H 3 "Location Lists" +.IX locations, lists +Each entry in a location list consists of two relative addresses +followed by a 2-byte length, followed by a block of contiguous +bytes. The length specifies the number of bytes in the block +that follows. The two addresses are the same size as used by +.Cf DW_FORM_addr +on the target machine. +.H 2 "Base Type Encodings" +.nr aX \n(Fg+1 +.IX base types +.IX types, base +The values of the constants used in the +.Cf DW_AT_encoding +attribute are given in Figure \n(aX. +.DF +.TS +box center; +l l +lf(CW) lf(CW) +. +Base type encoding name Value +_ +DW_ATE_address 0x1 +DW_ATE_boolean 0x2 +DW_ATE_complex_float 0x3 +DW_ATE_float 0x4 +DW_ATE_signed 0x5 +DW_ATE_signed_char 0x6 +DW_ATE_unsigned 0x7 +DW_ATE_unsigned_char 0x8 +DW_ATE_lo_user 0x80 +DW_ATE_hi_user 0xff +.TE +.FG "Base type encoding values" +.DE +.H 2 "Accessibility Codes" +.nr aX \n(Fg+1 +.IX accessibility +.IX declarations, accessibility +The encodings of the constants used in the +.Cf DW_AT_accessibility +attribute are given in Figure \n(aX. +.DF +.TS +box center; +l l +lf(CW) lf(CW) +. +Accessibility code name Value +_ +DW_ACCESS_public 1 +DW_ACCESS_protected 2 +DW_ACCESS_private 3 +.TE +.FG "Accessibility encodings" +.DE +.H 2 "Visibility Codes" +.nr aX \n(Fg+1 +The encodings of the constants used in the +.Cf DW_AT_visibility +.IX visibility +.IX declarations, visibility +attribute are given in Figure \n(aX. +.DF +.TS +box center; +l l +lf(CW) lf(CW) +. +Visibility code name Value +_ +DW_VIS_local 1 +DW_VIS_exported 2 +DW_VIS_qualified 3 +.TE +.FG "Visibility encodings" +.DE +.H 2 "Virtuality Codes" +.nr aX \n(Fg+1 +.IX virtuality +The encodings of the constants used in the +.Cf DW_AT_virtuality +attribute are given in Figure \n(aX. +.DF +.TS +box center; +l l +lf(CW) lf(CW) +. +Virtuality code name Value +_ +DW_VIRTUALITY_none 0 +DW_VIRTUALITY_virtual 1 +DW_VIRTUALITY_pure_virtual 2 +.TE +.FG "Virtuality encodings" +.DE +.H 2 "Source Languages" +.nr aX \n(Fg+1 +.IX languages +The encodings for source languages are given in Figure \n(aX. +Names marked with \(dg and their associated +values are reserved, but the languages +they represent are not supported in DWARF Version 2. +.DF +.TS +box center; +l l +lf(CW) lf(CW) +. +Language name Value +_ +DW_LANG_C89 0x0001 +DW_LANG_C 0x0002 +DW_LANG_Ada83\(dg 0x0003 +DW_LANG_C_plus_plus 0x0004 +DW_LANG_Cobol74\(dg 0x0005 +DW_LANG_Cobol85\(dg 0x0006 +DW_LANG_Fortran77 0x0007 +DW_LANG_Fortran90 0x0008 +DW_LANG_Pascal83 0x0009 +DW_LANG_Modula2 0x000a +DW_LANG_lo_user 0x8000 +DW_LANG_hi_user 0xffff +.TE +.FG "Language encodings" +.DE +.H 2 "Address Class Encodings" +.IX addresses, class +The value of the common address class encoding +.Cf DW_ADDR_none +is 0. +.H 2 "Identifier Case" +.IX identifiers, case +The encodings of the constants used in the +.Cf DW_AT_identifier_case +.nr aX \n(Fg+1 +attribute are given in Figure \n(aX. +.DF +.TS +box center; +l l +lf(CW) lf(CW) +. +Identifier Case Name Value +_ +DW_ID_case_sensitive 0 +DW_ID_up_case 1 +DW_ID_down_case 2 +DW_ID_case_insensitive 3 +.TE +.FG "Identifier case encodings" +.DE +.H 2 "Calling Convention Encodings" +.IX calling conventions +The encodings for the values of the +.Cf DW_AT_calling_convention +.nr aX \n(Fg+1 +attribute are given in Figure \n(aX. +.DF +.TS +box center; +l l +lf(CW) lf(CW) +. +Calling Convention Name Value +_ +DW_CC_normal 0x1 +DW_CC_program 0x2 +DW_CC_nocall 0x3 +DW_CC_lo_user 0x40 +DW_CC_hi_user 0xff +.TE +.FG "Calling convention encodings" +.DE +.H 2 "Inline Codes" +.IX subroutines, inline +The encodings of the constants used in the +.Cf DW_AT_inline +.nr aX \n(Fg+1 +attribute are given in Figure \n(aX. +.DF +.TS +box center; +l l +lf(CW) lf(CW) +. +Inline Code Name Value +_ +DW_INL_not_inlined 0 +DW_INL_inlined 1 +DW_INL_declared_not_inlined 2 +DW_INL_declared_inlined 3 +.TE +.FG "Inline encodings" +.DE +.H 2 "Array Ordering" +.IX arrays, ordering +The encodings for the values of the order attributes of arrays +.nr aX \n(Fg+1 +is given in Figure \n(aX. +.DF +.TS +box center; +l l +lf(CW) lf(CW) +. +Ordering name Value +_ +DW_ORD_row_major 0 +DW_ORD_col_major 1 +.TE +.FG "Ordering encodings" +.DE +.H 2 "Discriminant Lists" +.IX variants +.IX discriminated unions +.IX discriminants +The descriptors used in the +.Cf DW_AT_dicsr_list +attribute are encoded as 1-byte constants. +.nr aX \n(Fg+1 +The defined values are presented in Figure \n(aX. +.DF +.TS +box center; +l l +lf(CW) lf(CW) +. +Descriptor Name Value +_ +DW_DSC_label 0 +DW_DSC_range 1 +.TE +.FG "Discriminant descriptor encodings" +.DE +.H 2 "Name Lookup Table" +.IX lookup, by name +Each set of entries in the table of global names contained in the +.Cf .debug_pubnames +.IX \f(CW.debug_pubnames\fP %debugap +section begins with a header consisting of: a 4-byte length containing +the length of the set of entries for this compilation unit, not including +the length field itself; a 2-byte version identifier containing +the value 2 for DWARF Version 2; a 4-byte offset into the +.Cf .debug_info +section; and a 4-byte length containing the size in bytes +of the contents of the +.Cf .debug_info +section generated to represent this compilation unit. +This header is followed by a series of tuples. +Each tuple consists of a 4-byte offset +followed by a string of non-null bytes terminated by one null byte. +Each set is terminated by a 4-byte word containing the value 0. +.H 2 "Address Range Table" +.IX lookup, by address +Each set of entries in the table of address ranges contained in the +.Cf .debug_aranges +.IX \f(CW.debug_aranges\fP %debugaar +section begins with a header consisting of: a 4-byte length containing +the length of the set of entries for this compilation unit, not including +the length field itself; a 2-byte version identifier containing +the value 2 for DWARF Version 2; a 4-byte offset into the +.Cf .debug_info +section; a 1-byte unsigned integer containing the size in bytes of an +address (or the offset portion of an address for segmented addressing) +.IX addresses, offset portion +.IX addresses, size of +on the target system; and a 1-byte unsigned integer containing the +size in bytes of a segment descriptor on the target system. +This header is followed by a series of tuples. +Each tuple consists of an address and a length, each +in the size appropriate for an address on the target architecture. +The first tuple following the header in each set begins at +an offset that is a multiple of the size of a single tuple +(that is, twice the size of an address). The header is +padded, if necessary, to the appropriate boundary. +Each set of tuples is terminated by a 0 for the address and 0 for the length. +.H 2 "Line Number Information" +.IX line number information +.IX line number information, definitions +The sizes of the integers used in the line number and +call frame information sections are as follows: +.VL 15 +.LI "sbyte" +Signed 1-byte value. +.LI "ubyte" +Unsigned 1-byte value. +.LI "uhalf" +Unsigned 2-byte value. +.LI "sword" +Signed 4-byte value. +.LI "uword" +Unsigned 4-byte value. +.LI +.LE +.P +.IX Version 2 +The version number in the statement program prologue is 2 for +DWARF Version 2. +The boolean values ``true'' and ``false'' used by the statement +information program are encoded as a single byte containing the +value 0 for ``false,'' and a non-zero value for ``true.'' +The encodings for the pre-defined standard opcodes are given +.IX line number information, standard opcodes +.nr aX \n(Fg+1 +in Figure \n(aX. +.DF +.TS +box center; +l l +lf(CW) lf(CW) +. +Opcode Name Value +_ +DW_LNS_copy 1 +DW_LNS_advance_pc 2 +DW_LNS_advance_line 3 +DW_LNS_set_file 4 +DW_LNS_set_column 5 +DW_LNS_negate_stmt 6 +DW_LNS_set_basic_block 7 +DW_LNS_const_add_pc 8 +DW_LNS_fixed_advance_pc 9 +.TE +.FG "Standard Opcode Encodings" +.DE +The encodings for the pre-defined extended opcodes are given +.IX line number information, extended opcodes +.nr aX \n(Fg+1 +in Figure \n(aX. +.DF +.TS +box center; +l l +lf(CW) lf(CW) +. +Opcode Name Value +_ +DW_LNE_end_sequence 1 +DW_LNE_set_address 2 +DW_LNE_define_file 3 +.TE +.FG "Extended Opcode Encodings" +.DE +.H 2 "Macro Information" +.IX macro information +.IX source, files +The source line numbers and source file indices encoded in the +macro information section are represented as unsigned LEB128 numbers +as are the constants in an +.Cf DW_MACINFO_vendor_ext +entry. +The macinfo type is encoded as a single byte. The encodings are given +.nr aX \n(Fg+1 +in Figure \n(aX. +.DF +.TS +box center; +l l +lf(CW) lf(CW) +. +Macinfo Type Name Value +_ +DW_MACINFO_define 1 +DW_MACINFO_undef 2 +DW_MACINFO_start_file 3 +DW_MACINFO_end_file 4 +DW_MACINFO_vendor_ext 255 +.TE +.FG "Macinfo Type Encodings" +.DE +.H 2 "Call Frame Information" +.IX call frame information +The value of the CIE id in the CIE header is +.Cf 0xffffffff . +The initial value of the CIE version number is 1. +.P +Call frame instructions are encoded in one or more bytes. +.IX call frame information, instructions +The primary opcode is encoded in the high order two bits of +the first byte (that is, opcode = byte >> 6). +An operand or extended opcode may be encoded in the low order +6 bits. Additional operands are encoded in subsequent bytes. +The instructions and their encodings are presented +.nr aX \n(Fg+1 +in Figure \n(aX. +.DS +.TS +center box; +l l l l l +lf(CW) lf(CW) l l +lf(CW) lf(CW) l l +lf(CW) lf(CW) l l +lf(CW) lf(CW) lf(CW) l. +Instruction High 2 Bits Low 6 Bits Operand 1 Operand 2 +_ +DW_CFA_advance_loc 0x1 delta +DW_CFA_offset 0x2 register ULEB128 offset +DW_CFA_restore 0x3 register +DW_CFA_set_loc 0 0x01 address +DW_CFA_advance_loc1 0 0x02 1-byte delta +DW_CFA_advance_loc2 0 0x03 2-byte delta +DW_CFA_advance_loc4 0 0x04 4-byte delta +DW_CFA_offset_extended 0 0x05 ULEB128 register ULEB128 offset +DW_CFA_restore_extended 0 0x06 ULEB128 register +DW_CFA_undefined 0 0x07 ULEB128 register +DW_CFA_same_value 0 0x08 ULEB128 register +DW_CFA_register 0 0x09 ULEB128 register ULEB128 register +DW_CFA_remember_state 0 0x0a +DW_CFA_restore_state 0 0x0b +DW_CFA_def_cfa 0 0x0c ULEB128 register ULEB128 offset +DW_CFA_def_cfa_register 0 0x0d ULEB128 register +DW_CFA_def_cfa_offset 0 0x0e ULEB128 offset +DW_CFA_nop 0 0 +DW_CFA_lo_user 0 0x1c +DW_CFA_hi_user 0 0x3f +.TE +.FG "Call frame instruction encodings" +.DE +.H 2 "Dependencies" +The debugging information in this format is intended to exist in the +.Cf .debug_abbrev , +.Cf .debug_aranges , +.Cf .debug_frame , +.Cf .debug_info , +.Cf .debug_line , +.Cf .debug_loc , +.Cf .debug_macinfo , +.Cf .debug_pubnames +and +.Cf .debug_str +.IX \f(CW.debug_abbrev\fP %debugaab +.IX \f(CW.debug_aranges\fP %debugaar +.IX \f(CW.debug_frame\fP %debugaf +.IX \f(CW.debug_info\fP %debugai +.IX \f(CW.debug_line\fP %debugali +.IX \f(CW.debug_loc\fP %debugalo +.IX \f(CW.debug_macinfo\fP %debugam +.IX \f(CW.debug_pubnames\fP %debugap +.IX \f(CW.debug_str\fP %debugas +sections of an object file. +The information is not word-aligned, so the assembler must provide a +way for the compiler to produce 2-byte and 4-byte quantities without +alignment restrictions, and the linker must be able to +relocate a 4-byte reference at an arbitrary alignment. +In target architectures with 64-bit addresses, the assembler and linker +must similarly handle 8-byte references at arbitrary alignments. +.OP +.H 1 "FUTURE DIRECTIONS" +The \*(iX \*(tE is working on a specification for a set of interfaces +for reading DWARF information, that will hide changes in the +representation of that information from its consumers. It is +hoped that using these interfaces will make the transition from +DWARF Version 1 to Version 2 much simpler and will make it +easier for a single consumer to support objects using either +Version 1 or Version 2 DWARF. +.P +A draft of this specification is available for review from +\*(iX. The \*(tE wishes to stress, however, that the specification +is still in flux. +.OP +.HU "Appendix 1 -- Current Attributes by Tag Value" +.P +The list below enumerates the attributes that are most applicable to each type +of debugging information entry. +DWARF does not in general require that a given debugging information +entry contain a particular attribute or set of attributes. Instead, a +DWARF producer is free to generate any, all, or none of the attributes +described in the text as being applicable to a given entry. Other +attributes (both those defined within this document but not explicitly +associated with the entry in question, and new, vendor-defined ones) +may also appear in a given debugging entry. +Therefore, the list may be +taken as instructive, but cannot be considered definitive. +.sp +.sp +.DS +.TS +box, tab(:) ; +lfB lfB +lf(CW) lf(CW) . +TAG NAME:APPLICABLE ATTRIBUTES +_ +DW_TAG_access_declaration:DECL\(dg +:DW_AT_accessibility +:DW_AT_name +:DW_AT_sibling +_ +DW_TAG_array_type:DECL +:DW_AT_abstract_origin +:DW_AT_accessibility +:DW_AT_byte_size +:DW_AT_declaration +:DW_AT_name +:DW_AT_ordering +:DW_AT_sibling +:DW_AT_start_scope +:DW_AT_stride_size +:DW_AT_type +:DW_AT_visibility +_ +DW_TAG_base_type:DW_AT_bit_offset +:DW_AT_bit_size +:DW_AT_byte_size +:DW_AT_encoding +:DW_AT_name +:DW_AT_sibling +_ +DW_TAG_catch_block:DW_AT_abstract_origin +:DW_AT_high_pc +:DW_AT_low_pc +:DW_AT_segment +:DW_AT_sibling +.TE +.DE +.br +\(dg +.Cf DW_AT_decl_column , +.Cf DW_AT_decl_file , +.Cf DW_AT_decl_line . +.SK +.DS +.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value" + + + +.TS +box, tab(:) ; +lfB lfB +lf(CW) lf(CW) . +TAG NAME:APPLICABLE ATTRIBUTES +_ +DW_TAG_class_type:DECL +:DW_AT_abstract_origin +:DW_AT_accessibility +:DW_AT_byte_size +:DW_AT_declaration +:DW_AT_name +:DW_AT_sibling +:DW_AT_start_scope +:DW_AT_visibility +_ +DW_TAG_common_block:DECL +:DW_AT_declaration +:DW_AT_location +:DW_AT_name +:DW_AT_sibling +:DW_AT_visibility +_ +DW_TAG_common_inclusion:DECL +:DW_AT_common_reference +:DW_AT_declaration +:DW_AT_sibling +:DW_AT_visibility +_ +DW_TAG_compile_unit:DW_AT_base_types +:DW_AT_comp_dir +:DW_AT_identifier_case +:DW_AT_high_pc +:DW_AT_language +:DW_AT_low_pc +:DW_AT_macro_info +:DW_AT_name +:DW_AT_producer +:DW_AT_sibling +:DW_AT_stmt_list +_ +DW_TAG_const_type:DW_AT_sibling +:DW_AT_type +.TE +.DE +.br +.SK +.DS +.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value" + + + +.TS +box, tab(:) ; +lfB lfB +lf(CW) lf(CW) . +TAG NAME:APPLICABLE ATTRIBUTES +_ +DW_TAG_constant:DECL +:DW_AT_accessibility +:DW_AT_constant_value +:DW_AT_declaration +:DW_AT_external +:DW_AT_name +:DW_AT_sibling +:DW_AT_start_scope +:DW_AT_type +:DW_AT_visibility +_ +DW_TAG_entry_point:DW_AT_address_class +:DW_AT_low_pc +:DW_AT_name +:DW_AT_return_addr +:DW_AT_segment +:DW_AT_sibling +:DW_AT_static_link +:DW_AT_type +_ +DW_TAG_enumeration_type:DECL +:DW_AT_abstract_origin +:DW_AT_accessibility +:DW_AT_byte_size +:DW_AT_declaration +:DW_AT_name +:DW_AT_sibling +:DW_AT_start_scope +:DW_AT_visibility +_ +DW_TAG_enumerator:DECL +:DW_AT_const_value +:DW_AT_name +:DW_AT_sibling +_ +DW_TAG_file_type:DECL +:DW_AT_abstract_origin +:DW_AT_byte_size +:DW_AT_name +:DW_AT_sibling +:DW_AT_start_scope +:DW_AT_type +:DW_AT_visibility +.TE +.DE +.br +.SK +.DS +.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value" + + + +.TS +box, tab(:) ; +lfB lfB +lf(CW) lf(CW) . +TAG NAME:APPLICABLE ATTRIBUTES +_ +DW_TAG_formal_parameter:DECL +:DW_AT_abstract_origin +:DW_AT_artificial +:DW_AT_default_value +:DW_AT_is_optional +:DW_AT_location +:DW_AT_name +:DW_AT_segment +:DW_AT_sibling +:DW_AT_type +:DW_AT_variable_parameter +_ +DW_TAG_friend:DECL +:DW_AT_abstract_origin +:DW_AT_friend +:DW_AT_sibling +_ +DW_TAG_imported_declaration:DECL +:DW_AT_accessibility +:DW_AT_import +:DW_AT_name +:DW_AT_sibling +:DW_AT_start_scope +_ +DW_TAG_inheritance:DECL +:DW_AT_accessibility +:DW_AT_data_member_location +:DW_AT_sibling +:DW_AT_type +:DW_AT_virtuality +_ +DW_TAG_inlined_subroutine:DECL +:DW_AT_abstract_origin +:DW_AT_high_pc +:DW_AT_low_pc +:DW_AT_segment +:DW_AT_sibling +:DW_AT_return_addr +:DW_AT_start_scope +_ +DW_TAG_label:DW_AT_abstract_origin +:DW_AT_low_pc +:DW_AT_name +:DW_AT_segment +:DW_AT_start_scope +:DW_AT_sibling +.TE +.DE +.br +.SK +.DS +.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value" + + + +.TS +box, tab(:) ; +lfB lfB +lf(CW) lf(CW) . +TAG NAME:APPLICABLE ATTRIBUTES +_ +DW_TAG_lexical_block:DW_AT_abstract_origin +:DW_AT_high_pc +:DW_AT_low_pc +:DW_AT_name +:DW_AT_segment +:DW_AT_sibling +_ +DW_TAG_member:DECL +:DW_AT_accessibility +:DW_AT_byte_size +:DW_AT_bit_offset +:DW_AT_bit_size +:DW_AT_data_member_location +:DW_AT_declaration +:DW_AT_name +:DW_AT_sibling +:DW_AT_type +:DW_AT_visibility +_ +DW_TAG_module:DECL +:DW_AT_accessibility +:DW_AT_declaration +:DW_AT_high_pc +:DW_AT_low_pc +:DW_AT_name +:DW_AT_priority +:DW_AT_segment +:DW_AT_sibling +:DW_AT_visibility +_ +DW_TAG_namelist:DECL +:DW_AT_accessibility +:DW_AT_abstract_origin +:DW_AT_declaration +:DW_AT_sibling +:DW_AT_visibility +_ +DW_TAG_namelist_item:DECL +:DW_AT_namelist_item +:DW_AT_sibling +_ +DW_TAG_packed_type:DW_AT_sibling +:DW_AT_type +.TE +.DE +.br +.SK +.DS +.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value" + + + +.TS +box, tab(:) ; +lfB lfB +lf(CW) lf(CW) . +TAG NAME:APPLICABLE ATTRIBUTES +_ +DW_TAG_pointer_type:DW_AT_address_class +:DW_AT_sibling +:DW_AT_type +_ +DW_TAG_ptr_to_member_type:DECL +:DW_AT_abstract_origin +:DW_AT_address_class +:DW_AT_containing_type +:DW_AT_declaration +:DW_AT_name +:DW_AT_sibling +:DW_AT_type +:DW_AT_use_location +:DW_AT_visibility +_ +DW_TAG_reference_type:DW_AT_address_class +:DW_AT_sibling +:DW_AT_type +_ +DW_TAG_set_type:DECL +:DW_AT_abstract_origin +:DW_AT_accessibility +:DW_AT_byte_size +:DW_AT_declaration +:DW_AT_name +:DW_AT_start_scope +:DW_AT_sibling +:DW_AT_type +:DW_AT_visibility +_ +DW_TAG_string_type:DECL +:DW_AT_accessibility +:DW_AT_abstract_origin +:DW_AT_byte_size +:DW_AT_declaration +:DW_AT_name +:DW_AT_segment +:DW_AT_sibling +:DW_AT_start_scope +:DW_AT_string_length +:DW_AT_visibility +.TE +.DE +.SK +.DS +.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value" + + + +.TS +box, tab(:) ; +lfB lfB +lf(CW) lf(CW) . +TAG NAME:APPLICABLE ATTRIBUTES +_ +DW_TAG_structure_type:DECL +:DW_AT_abstract_origin +:DW_AT_accessibility +:DW_AT_byte_size +:DW_AT_declaration +:DW_AT_name +:DW_AT_sibling +:DW_AT_start_scope +:DW_AT_visibility +_ +DW_TAG_subprogram:DECL +:DW_AT_abstract_origin +:DW_AT_accessibility +:DW_AT_address_class +:DW_AT_artificial +:DW_AT_calling_convention +:DW_AT_declaration +:DW_AT_external +:DW_AT_frame_base +:DW_AT_high_pc +:DW_AT_inline +:DW_AT_low_pc +:DW_AT_name +:DW_AT_prototyped +:DW_AT_return_addr +:DW_AT_segment +:DW_AT_sibling +:DW_AT_specification +:DW_AT_start_scope +:DW_AT_static_link +:DW_AT_type +:DW_AT_visibility +:DW_AT_virtuality +:DW_AT_vtable_elem_location +.TE +.DE +.SK +.DS +.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value" + + + +.TS +box, tab(:) ; +lfB lfB +lf(CW) lf(CW) . +TAG NAME:APPLICABLE ATTRIBUTES +_ +DW_TAG_subrange_type:DECL +:DW_AT_abstract_origin +:DW_AT_accessibility +:DW_AT_byte_size +:DW_AT_count +:DW_AT_declaration +:DW_AT_lower_bound +:DW_AT_name +:DW_AT_sibling +:DW_AT_type +:DW_AT_upper_bound +:DW_AT_visibility +_ +DW_TAG_subroutine_type:DECL +:DW_AT_abstract_origin +:DW_AT_accessibility +:DW_AT_address_class +:DW_AT_declaration +:DW_AT_name +:DW_AT_prototyped +:DW_AT_sibling +:DW_AT_start_scope +:DW_AT_type +:DW_AT_visibility +_ +DW_TAG_template_type_param:DECL +:DW_AT_name +:DW_AT_sibling +:DW_AT_type +_ +DW_TAG_template_value_param:DECL +:DW_AT_name +:DW_AT_const_value +:DW_AT_sibling +:DW_AT_type +_ +DW_TAG_thrown_type:DECL +:DW_AT_sibling +:DW_AT_type +_ +DW_TAG_try_block:DW_AT_abstract_origin +:DW_AT_high_pc +:DW_AT_low_pc +:DW_AT_segment +:DW_AT_sibling +.TE +.DE +.br +.SK +.DS +.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value" + + + +.TS +box, tab(:) ; +lfB lfB +lf(CW) lf(CW) . +TAG NAME:APPLICABLE ATTRIBUTES +_ +DW_TAG_typedef:DECL +:DW_AT_abstract_origin +:DW_AT_accessibility +:DW_AT_declaration +:DW_AT_name +:DW_AT_sibling +:DW_AT_start_scope +:DW_AT_type +:DW_AT_visibility +_ +DW_TAG_union_type:DECL +:DW_AT_abstract_origin +:DW_AT_accessibility +:DW_AT_byte_size +:DW_AT_declaration +:DW_AT_friends +:DW_AT_name +:DW_AT_sibling +:DW_AT_start_scope +:DW_AT_visibility +_ +DW_TAG_unspecified_parameters:DECL +:DW_AT_abstract_origin +:DW_AT_artificial +:DW_AT_sibling +_ +DW_TAG_variable:DECL +:DW_AT_accessibility +:DW_AT_constant_value +:DW_AT_declaration +:DW_AT_external +:DW_AT_location +:DW_AT_name +:DW_AT_segment +:DW_AT_sibling +:DW_AT_specification +:DW_AT_start_scope +:DW_AT_type +:DW_AT_visibility +.TE +.DE +.br +.SK +.DS +.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value" + + + +.TS +box, tab(:) ; +lfB lfB +lf(CW) lf(CW) . +TAG NAME:APPLICABLE ATTRIBUTES +_ +DW_TAG_variant:DECL +:DW_AT_accessibility +:DW_AT_abstract_origin +:DW_AT_declaration +:DW_AT_discr_list +:DW_AT_discr_value +:DW_AT_sibling +_ +DW_TAG_variant_part:DECL +:DW_AT_accessibility +:DW_AT_abstract_origin +:DW_AT_declaration +:DW_AT_discr +:DW_AT_sibling +:DW_AT_type +_ +DW_TAG_volatile_type:DW_AT_sibling +:DW_AT_type +_ +DW_TAG_with_statement:DW_AT_accessibility +:DW_AT_address_class +:DW_AT_declaration +:DW_AT_high_pc +:DW_AT_location +:DW_AT_low_pc +:DW_AT_segment +:DW_AT_sibling +:DW_AT_type +:DW_AT_visibility +.TE +.DE +.SK +.OP +.HU "Appendix 2 -- Organization of Debugging Information" +The following diagram depicts the relationship of the abbreviation +tables contained in the +.Cf .debug_abbrev +section to the information contained in the +.Cf .debug_info +section. Values are given in symbolic form, where possible. +.DF +.nf +.PS +scale=100 +define t201 | +[ box invis ht 154 wid 295 with .sw at 0,0 +"\f(CW\s9\&1\f1\s0" at 0,147 ljust +"\f(CW\s9\&DW_TAG_compile_unit\f1\s0" at 0,133 ljust +"\f(CW\s9\&DW_CHILDREN_yes\f1\s0" at 0,119 ljust +"\f(CW\s9\&DW_AT_name DW_FORM_string\f1\s0" at 0,105 ljust +"\f(CW\s9\&DW_AT_producer DW_FORM_string\f1\s0" at 0,91 ljust +"\f(CW\s9\&DW_AT_compdir DW_FORM_string\f1\s0" at 0,77 ljust +"\f(CW\s9\&DW_AT_language DW_FORM_data1\f1\s0" at 0,63 ljust +"\f(CW\s9\&DW_AT_low_poc DW_FORM_addr\f1\s0" at 0,49 ljust +"\f(CW\s9\&DW_AT_high_pc DW_FORM_addr\f1\s0" at 0,35 ljust +"\f(CW\s9\&DW_AT_stmt_list DW_FORM_indirect\f1\s0" at 0,21 ljust +"\f(CW\s9\&0 0\f1\s0" at 0,7 ljust +] | + +define t103 | +[ box invis ht 42 wid 74 with .sw at 0,0 +"\f(CW\s9\&4\f1\s0" at 0,35 ljust +"\f(CW\s9\&\"POINTER\"\f1\s0" at 0,21 ljust +"\f(CW\s9\&\f1\s0" at 0,7 ljust +] | + +define t177 | +[ box invis ht 28 wid 13 with .sw at 0,0 +"\f(CW\s9\&3\f1\s0" at 0,21 ljust +"\f(CW\s9\&\f1\s0" at 0,7 ljust +] | + +define t224 | +[ box invis ht 84 wid 280 with .sw at 0,0 +"\f(CW\s9\&4\f1\s0" at 0,77 ljust +"\f(CW\s9\&DW_TAG_typedef\f1\s0" at 0,63 ljust +"\f(CW\s9\&DW_CHILDREN_no\f1\s0" at 0,49 ljust +"\f(CW\s9\&DW_AT_name DW_FORM_string\f1\s0" at 0,35 ljust +"\f(CW\s9\&DW_AT_type DW_FORM_ref4 \f1\s0" at 0,21 ljust +"\f(CW\s9\&0 0 \f1\s0" at 0,7 ljust +] | + +define t149 | +[ box invis ht 28 wid 51 with .sw at 0,0 +"\f(CW\s9\&4\f1\s0" at 0,21 ljust +"\f(CW\s9\&\"strp\"\f1\s0" at 0,7 ljust +] | + +define t205 | +[ box invis ht 98 wid 280 with .sw at 0,0 +"\f(CW\s9\&2\f1\s0" at 0,91 ljust +"\f(CW\s9\&DW_TAG_base_type\f1\s0" at 0,77 ljust +"\f(CW\s9\&DW_CHILDREN_no\f1\s0" at 0,63 ljust +"\f(CW\s9\&DW_AT_name DW_FORM_string\f1\s0" at 0,49 ljust +"\f(CW\s9\&DW_AT_encoding DW_FORM_data1\f1\s0" at 0,35 ljust +"\f(CW\s9\&DW_AT_byte_size DW_FORM_data1\f1\s0" at 0,21 ljust +"\f(CW\s9\&0 0\f1\s0" at 0,7 ljust +] | + +define t126 | +[ box invis ht 126 wid 257 with .sw at 0,0 +"\f(CW\s9\&\"myfile.c\"\f1\s0" at 0,119 ljust +"\f(CW\s9\&\"Best Compiler Corp: Version 1.3\"\f1\s0" at 0,105 ljust +"\f(CW\s9\&\"mymachine:/home/mydir/src:\"\f1\s0" at 0,91 ljust +"\f(CW\s9\&DW_LANG_C89\f1\s0" at 0,77 ljust +"\f(CW\s9\&0x0\f1\s0" at 0,63 ljust +"\f(CW\s9\&0x55\f1\s0" at 0,49 ljust +"\f(CW\s9\&DW_FORM_data4\f1\s0" at 0,35 ljust +"\f(CW\s9\&0x0\f1\s0" at 0,21 ljust +"\f(CW\s9\&\f1\s0" at 0,7 ljust +] | + +define t219 | +[ box invis ht 70 wid 260 with .sw at 0,0 +"\f(CW\s9\&3\f1\s0" at 0,63 ljust +"\f(CW\s9\&DW_TAG_pointer_type\f1\s0" at 0,49 ljust +"\f(CW\s9\&DW_CHILDREN_no\f1\s0" at 0,35 ljust +"\f(CW\s9\&DW_AT_type DW_FORM_ref4\f1\s0" at 0,21 ljust +"\f(CW\s9\&0 0\f1\s0" at 0,7 ljust +] | + +define t109 | +[ box invis ht 42 wid 165 with .sw at 0,0 +"\f(CW\s9\&\"char\"\f1\s0" at 0,35 ljust +"\f(CW\s9\&DW_ATE_unsigned_char\f1\s0" at 0,21 ljust +"\f(CW\s9\&1\f1\s0" at 0,7 ljust +] | + +box invis ht 704 wid 680 with .sw at 0,0 +t201 with .nw at 376,657 +box ht 520 wid 320 with .nw at 360,672 +box ht 208 wid 280 with .nw at 24,208 +t103 with .nw at 40,353 +t177 with .nw at 40,398 +line from 360,176 to 680,176 +line from 360,280 to 680,280 +line from 360,368 to 680,368 +line from 360,488 to 680,488 +t224 with .nw at 376,270 +"\f(CW\s9\&0\f1\s0" at 376,164 ljust +"\f(CW\s9\&0\f1\s0" at 40,289 ljust +"\fI\s9\&e2\f1\s0" at 40,317 ljust +"\fI\s9\&e2:\f1\s0" at 0,389 ljust +"\f(CW\s9\&2\f1\s0" at 44,176 ljust +line from 24,128 to 304,128 +"\f(CW\s9\&...\f1\s0" at 44,113 ljust +t149 with .nw at 44,88 +"\fI\s9\&e2\f1\s0" at 44,49 ljust +"\f(CW\s9\&...\f1\s0" at 44,17 ljust +box ht 416 wid 280 with .nw at 24,688 +"\fI\s9\&length\f1\s0" at 44,192 ljust +"\f(CW\s9\&4\f1\s0" at 48,140 +"\fI\s9\&a1 (abbreviation table offset)\f1\s0" at 44,160 ljust +"\f(CW\s9\&4\f1\s0" at 44,624 +"\fI\s9\&a1 (abbreviation table offset)\f1\s0" at 40,640 ljust +t205 with .nw at 376,477 +"\fI\s9\&a1:\f1\s0" at 348,657 rjust +"\fI\s9\&length\f1\s0" at 40,672 ljust +"\fR\s10\&Abbreviation Table - .debug_abbrev\f1\s0" at 384,678 ljust +"\fR\s10\&Compilation Unit 1 - .debug_info\f1\s0" at 68,694 ljust +"\fR\s10\&Compilation Unit 2 - .debug_info\f1\s0" at 64,218 ljust +"\f(CW\s9\&2\f1\s0" at 44,656 +"\f(CW\s9\&1\f1\s0" at 44,605 +t126 with .nw at 36,599 +line from 24,616 to 304,616 +"\f(CW\s9\&2\f1\s0" at 40,461 ljust +t219 with .nw at 376,359 +line from 24,96 to 304,96 +line from 24,32 to 304,32 +t109 with .nw at 40,449 +"\fI\s9\&e1\f1\s0" at 40,373 ljust +"\fI\s9\&e1:\f1\s0" at 0,461 ljust +line from 24,480 to 304,480 +line from 24,400 to 304,400 +line from 24,360 to 304,360 +line from 24,304 to 304,304 +.PE +.fi +.DE +.SK +.OP +.HU "Appendix 3 -- Statement Program Examples" +.P +Consider this simple source file and the resulting machine code for +the Intel 8086 processor: +.DS +.S -2 +.TS +; +lf(CW) lf(CW) s +lf(CW) lf(CW) s +lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) s +lf(CW) lf(CW) s +lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) s +lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) s +lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) s +lf(CW) lf(CW) lf(CW). +1: int +2: main() + 0x239: push pb + 0x23a: mov bp,sp +3: { +4: printf("Omit needless words\en"); + 0x23c: mov ax,0xaa + 0x23f: push ax + 0x240: call _printf + 0x243: pop cx +5: exit(0); + 0x244: xor ax,ax + 0x246: push ax + 0x247: call _exit + 0x24a: pop cx +6: } + 0x24b: pop bp + 0x24c: ret +7: + 0x24d: +.TE +.S +2 +.DE +.P +If the statement program prologue specifies the following: +.DS +.S -2 +.TS +; +lf(CW) lf(CW). +minimum_instruction_length 1 +opcode_base 10 +line_base 1 +line_range 15 +.TE +.S +2 +.DE +.P +Then one encoding of the statement program would occupy 12 bytes +(the opcode \f(CWSPECIAL(\fIm\fP, \fIn\fP)\fR indicates the special +opcode generated for a line increment of \fIm\fP and an address increment +of \fIn\fP): +.DS +.S -2 +.TS +; +l l l +lf(CW) lf(CW) lf(CW). +Opcode Operand Byte Stream +_ +DW_LNS_advance_pc LEB128(0x239) 0x2, 0xb9, 0x04 +SPECIAL(2, 0) 0xb +SPECIAL(2, 3) 0x38 +SPECIAL(1, 8) 0x82 +SPECIAL(1, 7) 0x73 +DW_LNS_advance_pc LEB128(2) 0x2, 0x2 +DW_LNE_end_sequence 0x0, 0x1, 0x1 +.TE +.S +2 +.DE +.P +An alternate encoding of the same program using standard opcodes to +advance the program counter would occupy 22 bytes: +.DS +.S -2 +.TS +; +l l l +lf(CW) lf(CW) lf(CW). +Opcode Operand Byte Stream +_ +DW_LNS_fixed_advance_pc 0x239 0x9, 0x39, 0x2 +SPECIAL(2, 0) 0xb +DW_LNS_fixed_advance_pc 0x3 0x9, 0x3, 0x0 +SPECIAL(2, 0) 0xb +DW_LNS_fixed_advance_pc 0x8 0x9, 0x8, 0x0 +SPECIAL(1, 0) 0xa +DW_LNS_fixed_advance_pc 0x7 0x9, 0x7, 0x0 +SPECIAL(1, 0) 0xa +DW_LNS_fixed_advance_pc 0x2 0x9, 0x2, 0x0 +DW_LNE_end_sequence 0x0, 0x1, 0x1 +.TE +.S +2 +.DE +.SK +.OP +.HU "Appendix 4 -- Encoding and decoding variable length data" +.ta .5i +.5i +.5i +.5i +.5i +.5i +.5i +.5i +.P +Here are algorithms expressed in a C-like pseudo-code to encode and decode +signed and unsigned numbers in LEB128: +.P +\fBEncode an unsigned integer:\fP +.br +.DS +.S -2 +\f(CWdo +{ + byte = low order 7 bits of value; + value >>= 7; + if (value != 0) /* more bytes to come */ + set high order bit of byte; + emit byte; +} while (value != 0);\fP +.S +2 +.DE +.P +\fBEncode a signed integer:\fP +.br +.DS +.S -2 +\f(CWmore = 1; +negative = (value < 0); +size = no. of bits in signed integer; +while(more) +{ + byte = low order 7 bits of value; + value >>= 7; + /* the following is unnecessary if the implementation of >>= + * uses an arithmetic rather than logical shift for a signed + * left operand + */ + if (negative) + /* sign extend */ + value |= - (1 << (size - 7)); + /* sign bit of byte is 2nd high order bit (0x40) */ + if ((value == 0 && sign bit of byte is clear) || + (value == -1 && sign bit of byte is set)) + more = 0; + else + set high order bit of byte; + emit byte; +}\fP +.S +2 +.DE +.SK +.ta .5i +.5i +.5i +.5i +.5i +.5i +.5i +.5i +.P +\fBDecode unsigned LEB128 number:\fP +.br +.DS +.S -2 +\f(CWresult = 0; +shift = 0; +while(true) +{ + byte = next byte in input; + result |= (low order 7 bits of byte << shift); + if (high order bit of byte == 0) + break; + shift += 7; +}\fP +.S +2 +.DE +.P +\fBDecode signed LEB128 number:\fP +.br +.DS +.S -2 +\f(CWresult = 0; +shift = 0; +size = no. of bits in signed integer; +while(true) +{ + byte = next byte in input; + result |= (low order 7 bits of byte << shift); + shift += 7; + /* sign bit of byte is 2nd high order bit (0x40) */ + if (high order bit of byte == 0) + break; +} +if ((shift < size) && (sign bit of byte is set)) + /* sign extend */ + result |= - (1 << shift);\fP +.S +2 +.DE +.SK +.OP +.HU "Appendix 5 -- Call Frame Information Examples" +The following example uses a hypothetical RISC machine in the style of +the Motorola 88000. +.BL +.LI +Memory is byte addressed. +.LI +Instructions are all 4-bytes each and word aligned. +.LI +Instruction operands are typically of the form: +.br +.DS + +.DE +.LI +The address for the load and store instructions is computed by +adding the contents of the source register with the constant. +.LI +There are 8 4-byte registers: +.br +.DS + R0 always 0 + R1 holds return address on call + R2-R3 temp registers (not preserved on call) + R4-R6 preserved on call + R7 stack pointer. +.DE +.LI +The stack grows in the negative direction. +.LE +.P +The following are two code fragments from a subroutine +called \f(CWfoo\fP that +uses a frame pointer (in addition to the stack pointer.) The first +column values are byte addresses. +.DS +.S -2 +.TS +; +lf(CW) lf(CW) s s +lf(CW) lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) lf(CW) lf(CW) +lf(CW) lf(CW) s s +lf(CW) lf(CW) s s +lf(CW) lf(CW) s s +lf(CW) lf(CW) lf(CW) lf(CW). + ;; start prologue +foo sub R7, R7, ; Allocate frame +foo+4 store R1, R7, (-4) ; Save the return address +foo+8 store R6, R7, (-8) ; Save R6 +foo+12 add R6, R7, 0 ; R6 is now the Frame ptr +foo+16 store R4, R6, (-12) ; Save a preserve reg. + ;; This subroutine does not change R5 + ... + ;; Start epilogue (R7 has been returned to entry value) +foo+64 load R4, R6, (-12) ; Restore R4 +foo+68 load R6, R7, (-8) ; Restore R6 +foo+72 load R1, R7, (-4) ; Restore return address +foo+76 add R7, R7, ; Deallocate frame +foo+80 jump R ; Return +foo+84 +.TE +.S +2 +.DE +.SK +The table for the \f(CWfoo\fP subroutine is as follows. +It is followed by the +corresponding fragments from the +.Cf .debug_frame +section. +.DS +.S -2 +.TS +tab(|); +lf(CW) lf(CW) lf(CW) lf(CW) lf(CW) lf(CW) lf(CW) lf(CW) lf(CW) lf(CW) lf(CW). +Loc|CFA|R0|R1|R2|R3|R4|R5|R6|R7|R8 +foo|[R7]+0|s|u|u|u|s|s|s|s|r1 +foo+4|[R7]+fsize|s|u|u|u|s|s|s|s|r1 +foo+8|[R7]+fsize|s|u|u|u|s|s|s|s|c4 +foo+12|[R7]+fsize|s|u|u|u|s|s|c8|s|c4 +foo+16|[R6]+fsize|s|u|u|u|s|s|c8|s|c4 +foo+20|[R6]+fsize|s|u|u|u|c12|s|c8|s|c4 +... +foo+64|[R6]+fsize|s|u|u|u|c12|s|c8|s|c4 +foo+68|[R6]+fsize|s|u|u|u|s|s|c8|s|c4 +foo+72|[R7]+fsize|s|u|u|u|s|s|s|s|c4 +foo+76|[R7]+fsize|s|u|u|u|s|s|s|s|r1 +foo+80|[R7]+0|s|u|u|u|s|s|s|s|r1 +.TE +.TS +; +l s +l l. +notes: +1. R8 is the return address +2. s = same_value rule +3. u = undefined rule +4. rN = register(N) rule +5. cN = offset(N) rule +.sp +.sp +.TE +.S +2 +.DE +.P +Common Information Entry (CIE): +.DS +.S -2 +.TS +; +lf(CW) lf(CW) lf(CW). +cie 32 ; length +cie+4 0xffffffff ; CIE_id +cie+8 1 ; version +cie+9 0 ; augmentation +cie+10 4 ; code_alignment_factor +cie+11 4 ; data_alignment_factor +cie+12 8 ; R8 is the return addr. +cie+13 DW_CFA_def_cfa (7, 0) ; CFA = [R7]+0 +cie+16 DW_CFA_same_value (0) ; R0 not modified (=0) +cie+18 DW_CFA_undefined (1) ; R1 scratch +cie+20 DW_CFA_undefined (2) ; R2 scratch +cie+22 DW_CFA_undefined (3) ; R3 scratch +cie+24 DW_CFA_same_value (4) ; R4 preserve +cie+26 DW_CFA_same_value (5) ; R5 preserve +cie+28 DW_CFA_same_value (6) ; R6 preserve +cie+30 DW_CFA_same_value (7) ; R7 preserve +cie+32 DW_CFA_register (8, 1) ; R8 is in R1 +cie+35 DW_CFA_nop ; padding +cie+36 +.TE +.S +2 +.DE +.SK +.P +Frame Description Entry (FDE): +.DS +.S -2 +.TS +; +lf(CW) lf(CW) lf(CW). +fde 40 ; length +fde+4 cie ; CIE_ptr +fde+8 foo ; initial_location +fde+12 84 ; address_range +fde+16 DW_CFA_advance_loc(1) ; instructions +fde+17 DW_CFA_def_cfa_offset(/4) ; assuming < 512 +fde+19 DW_CFA_advance_loc(1) +fde+20 DW_CFA_offset(8,1) +fde+22 DW_CFA_advance_loc(1) +fde+23 DW_CFA_offset(6,2) +fde+25 DW_CFA_advance_loc(1) +fde+26 DW_CFA_def_cfa_register(6) +fde+28 DW_CFA_advance_loc(1) +fde+29 DW_CFA_offset(4,3) +fde+31 DW_CFA_advance_loc(11) +fde+32 DW_CFA_restore(4) +fde+33 DW_CFA_advance_loc(1) +fde+34 DW_CFA_restore(6) +fde+35 DW_CFA_def_cfa_register(7) +fde+37 DW_CFA_advance_loc(1) +fde+38 DW_CFA_restore(8) +fde+39 DW_CFA_advance_loc(1) +fde+40 DW_CFA_def_cfa_offset(0) +fde+42 DW_CFA_nop ; padding +fde+43 DW_CFA_nop ; padding +fde+44 +.TE +.S +2 +.DE +.S +1 + +'\" +'\" Table of Contents stuff +'\" +.de TP +.sp 4 +.. +.VM +.de TY +.ce 1 +Table of Contents +.sp +.. +.nr Lf 1 +.ds Lf List of Figures +.SK +.TC 1 1 7 0 diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf.v2.pdf Binary file tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf.v2.pdf has changed diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_abbrev.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_abbrev.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,257 @@ +/* + + Copyright (C) 2000,2001,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the above address. +*/ + + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_abbrev.h" + +int +dwarf_get_abbrev(Dwarf_Debug dbg, + Dwarf_Unsigned offset, + Dwarf_Abbrev * returned_abbrev, + Dwarf_Unsigned * length, + Dwarf_Unsigned * abbr_count, Dwarf_Error * error) +{ + Dwarf_Small *abbrev_ptr; + Dwarf_Small *abbrev_section_end; + Dwarf_Half attr; + Dwarf_Half attr_form; + Dwarf_Abbrev ret_abbrev; + Dwarf_Unsigned labbr_count = 0; + Dwarf_Unsigned utmp; + + + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + if (dbg->de_debug_abbrev == 0) { + /* Loads abbrev section (and .debug_info as we do those + together). */ + int res = _dwarf_load_debug_info(dbg, error); + + if (res != DW_DLV_OK) { + return res; + } + } + + if (offset >= dbg->de_debug_abbrev_size) { + return (DW_DLV_NO_ENTRY); + } + + + ret_abbrev = (Dwarf_Abbrev) _dwarf_get_alloc(dbg, DW_DLA_ABBREV, 1); + if (ret_abbrev == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + ret_abbrev->ab_dbg = dbg; + if (returned_abbrev == 0 || abbr_count == 0) { + dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); + _dwarf_error(dbg, error, DW_DLE_DWARF_ABBREV_NULL); + return (DW_DLV_ERROR); + } + + + *abbr_count = 0; + if (length != NULL) + *length = 1; + + abbrev_ptr = dbg->de_debug_abbrev + offset; + abbrev_section_end = + dbg->de_debug_abbrev + dbg->de_debug_abbrev_size; + + DECODE_LEB128_UWORD(abbrev_ptr, utmp); + ret_abbrev->ab_code = (Dwarf_Word) utmp; + if (ret_abbrev->ab_code == 0) { + *returned_abbrev = ret_abbrev; + *abbr_count = 0; + if (length) { + *length = 1; + } + return (DW_DLV_OK); + } + + DECODE_LEB128_UWORD(abbrev_ptr, utmp); + ret_abbrev->ab_tag = utmp; + ret_abbrev->ab_has_child = *(abbrev_ptr++); + ret_abbrev->ab_abbrev_ptr = abbrev_ptr; + + do { + Dwarf_Unsigned utmp2; + + DECODE_LEB128_UWORD(abbrev_ptr, utmp2); + attr = (Dwarf_Half) utmp2; + DECODE_LEB128_UWORD(abbrev_ptr, utmp2); + attr_form = (Dwarf_Half) utmp2; + + if (attr != 0) + (labbr_count)++; + + } while (abbrev_ptr < abbrev_section_end && + (attr != 0 || attr_form != 0)); + + if (abbrev_ptr > abbrev_section_end) { + dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); + _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR); + return (DW_DLV_ERROR); + } + + if (length != NULL) + *length = abbrev_ptr - dbg->de_debug_abbrev - offset; + + *returned_abbrev = ret_abbrev; + *abbr_count = labbr_count; + return (DW_DLV_OK); +} + +int +dwarf_get_abbrev_code(Dwarf_Abbrev abbrev, + Dwarf_Unsigned * returned_code, + Dwarf_Error * error) +{ + if (abbrev == NULL) { + _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); + return (DW_DLV_ERROR); + } + + *returned_code = abbrev->ab_code; + return (DW_DLV_OK); +} + +int +dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev, + Dwarf_Half * returned_tag, Dwarf_Error * error) +{ + if (abbrev == NULL) { + _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); + return (DW_DLV_ERROR); + } + + *returned_tag = abbrev->ab_tag; + return (DW_DLV_OK); +} + + +int +dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev, + Dwarf_Signed * returned_flag, + Dwarf_Error * error) +{ + if (abbrev == NULL) { + _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); + return (DW_DLV_ERROR); + } + + *returned_flag = abbrev->ab_has_child; + return (DW_DLV_OK); +} + + +int +dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev, + Dwarf_Signed index, + Dwarf_Half * returned_attr_num, + Dwarf_Signed * form, + Dwarf_Off * offset, Dwarf_Error * error) +{ + Dwarf_Byte_Ptr abbrev_ptr = 0; + Dwarf_Byte_Ptr abbrev_end = 0; + Dwarf_Byte_Ptr mark_abbrev_ptr = 0; + Dwarf_Half attr = 0; + Dwarf_Half attr_form = 0; + + if (index < 0) + return (DW_DLV_NO_ENTRY); + + if (abbrev == NULL) { + _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); + return (DW_DLV_ERROR); + } + + if (abbrev->ab_code == 0) { + return (DW_DLV_NO_ENTRY); + } + + if (abbrev->ab_dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + + abbrev_ptr = abbrev->ab_abbrev_ptr; + abbrev_end = + abbrev->ab_dbg->de_debug_abbrev + + abbrev->ab_dbg->de_debug_abbrev_size; + + for (attr = 1, attr_form = 1; + index >= 0 && abbrev_ptr < abbrev_end && (attr != 0 || + attr_form != 0); + index--) { + Dwarf_Unsigned utmp4; + + mark_abbrev_ptr = abbrev_ptr; + DECODE_LEB128_UWORD(abbrev_ptr, utmp4); + attr = (Dwarf_Half) utmp4; + DECODE_LEB128_UWORD(abbrev_ptr, utmp4); + attr_form = (Dwarf_Half) utmp4; + } + + if (abbrev_ptr >= abbrev_end) { + _dwarf_error(abbrev->ab_dbg, error, DW_DLE_ABBREV_DECODE_ERROR); + return (DW_DLV_ERROR); + } + + if (index >= 0) { + return (DW_DLV_NO_ENTRY); + } + + if (form != NULL) + *form = attr_form; + if (offset != NULL) + *offset = mark_abbrev_ptr - abbrev->ab_dbg->de_debug_abbrev; + + *returned_attr_num = (attr); + return DW_DLV_OK; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_abbrev.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_abbrev.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,45 @@ +/* + + Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + + +struct Dwarf_Abbrev_s { + Dwarf_Word ab_code; + Dwarf_Half ab_tag; + Dwarf_Small ab_has_child; + Dwarf_Byte_Ptr ab_abbrev_ptr; + Dwarf_Debug ab_dbg; +}; diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_addr_finder.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_addr_finder.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,688 @@ +/* + + Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* This code used by SGI-IRIX rqs processing, not needed by + any other system or application. +*/ + +#include "config.h" +#include "libdwarfdefs.h" +#ifdef HAVE_ELF_H +#include +#endif +#include +#include +#include "dwarf_base_types.h" +#include "dwarf_alloc.h" +#include "dwarf_opaque.h" +#include "dwarf_arange.h" +#include "dwarf_line.h" +#include "dwarf_frame.h" +#include +#include "dwarf_error.h" + +typedef unsigned long long ull; + +static int do_this_die_and_dealloc(Dwarf_Debug dbg, Dwarf_Die die, + int *errval); +static int + handle_debug_info(Dwarf_Debug dbg, int *errval); +static int + handle_debug_frame(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, int *errval); +static int + handle_debug_aranges(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, int *errval); +static int + handle_debug_line(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_addr_callback_func cb_func, int *errval); +static int + handle_debug_loc(void); + + +static Dwarf_addr_callback_func send_addr_note; + +int +_dwarf_addr_finder(dwarf_elf_handle elf_file_ptr, + Dwarf_addr_callback_func cb_func, int *dwerr) +{ + + Dwarf_Error err = 0; + Dwarf_Debug dbg = 0; + int res = 0; + int errval = 0; + int sections_found = 0; + + res = dwarf_elf_init(elf_file_ptr, DW_DLC_READ, /* errhand */ 0, + /* errarg */ 0, &dbg, &err); + if (res == DW_DLV_ERROR) { + int errv = (int) dwarf_errno(err); + + return errv; + } + if (res == DW_DLV_NO_ENTRY) { + return res; + } + + send_addr_note = cb_func; + + res = handle_debug_info(dbg, &errval); + switch (res) { + case DW_DLV_OK: + ++sections_found; + break; + case DW_DLV_NO_ENTRY: + + break; + default: + case DW_DLV_ERROR: + dwarf_finish(dbg, &err); + *dwerr = errval; + return res; + } + + res = handle_debug_aranges(dbg, cb_func, &errval); + switch (res) { + case DW_DLV_OK: + ++sections_found; + break; + case DW_DLV_NO_ENTRY: + break; + default: + case DW_DLV_ERROR: + dwarf_finish(dbg, &err); + *dwerr = errval; + return res; + } + res = handle_debug_frame(dbg, cb_func, &errval); + switch (res) { + case DW_DLV_OK: + ++sections_found; + break; + case DW_DLV_NO_ENTRY: + break; + default: + case DW_DLV_ERROR: + dwarf_finish(dbg, &err); + *dwerr = errval; + return res; + } + + res = handle_debug_loc(); /* does nothing */ + switch (res) { + case DW_DLV_OK: + ++sections_found; + break; + case DW_DLV_NO_ENTRY: + break; + default: + case DW_DLV_ERROR: + /* IMPOSSIBLE : handle_debug_loc cannot return this */ + dwarf_finish(dbg, &err); + *dwerr = errval; + return res; + } + + + + *dwerr = 0; + res = dwarf_finish(dbg, &err); + if (res == DW_DLV_ERROR) { + *dwerr = (int) dwarf_errno(err); + return DW_DLV_ERROR; + } + if (sections_found == 0) { + return DW_DLV_NO_ENTRY; + } + return DW_DLV_OK; + +} + +/* + Return DW_DLV_OK, ERROR, or NO_ENTRY. +*/ +static int +handle_debug_info(Dwarf_Debug dbg, int *errval) +{ + Dwarf_Unsigned nxtoff = 1; + Dwarf_Unsigned hdr_length; + Dwarf_Half version_stamp; + Dwarf_Unsigned abbrev_offset; + Dwarf_Half addr_size; + Dwarf_Error err; + int terminate_now = 0; + int res = 0; + Dwarf_Die sibdie; + int sibres; + int nres = DW_DLV_OK; + + + for (nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp, + &abbrev_offset, + &addr_size, &nxtoff, &err); + terminate_now == 0 && nres == DW_DLV_OK; + nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp, + &abbrev_offset, + &addr_size, &nxtoff, &err) + ) { + + Dwarf_Die curdie = 0; + + /* try to get the compilation unit die */ + sibres = dwarf_siblingof(dbg, curdie, &sibdie, &err); + if (sibres == DW_DLV_OK) { + res = do_this_die_and_dealloc(dbg, sibdie, errval); + switch (res) { + case DW_DLV_OK: + break; + case DW_DLV_NO_ENTRY: + break; + default: + case DW_DLV_ERROR: + return DW_DLV_ERROR; + } + } else if (sibres == DW_DLV_ERROR) { + *errval = (int) dwarf_errno(err); + return DW_DLV_ERROR; + } else { + /* NO ENTRY! */ + /* impossible? */ + } + + } + if (nres == DW_DLV_ERROR) { + int localerr = (int) dwarf_errno(err); + + *errval = localerr; + return DW_DLV_ERROR; + } + return DW_DLV_OK; +} + +static int + might_have_addr[] = { + DW_AT_high_pc, + DW_AT_low_pc, +}; +static int + might_have_locdesc[] = { + DW_AT_segment, + DW_AT_return_addr, + DW_AT_frame_base, + DW_AT_static_link, + DW_AT_data_member_location, + DW_AT_string_length, + DW_AT_location, + DW_AT_use_location, + DW_AT_vtable_elem_location, +}; + +/* + Return DW_DLV_OK if handling this went ok. +*/ +static int +handle_attr_addr(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attrnum, + Dwarf_Error * perr) +{ + int res = DW_DLV_OK; + Dwarf_Off offset; + Dwarf_Addr addr; + Dwarf_Half form; + int ares; + + Dwarf_Attribute attr; + + ares = dwarf_attr(die, attrnum, &attr, perr); + if (ares == DW_DLV_OK) { + int formres = dwarf_whatform(attr, &form, perr); + + switch (formres) { + case DW_DLV_OK: + break; + case DW_DLV_ERROR: + case DW_DLV_NO_ENTRY: /* impossible. */ + return formres; + + } + + switch (form) { + case DW_FORM_ref_addr: + case DW_FORM_addr: + res = dwarf_attr_offset(die, attr, &offset, perr); + if (res == DW_DLV_OK) { + ares = dwarf_formaddr(attr, &addr, perr); + if (ares == DW_DLV_OK) { + send_addr_note(DW_SECTION_INFO, offset, addr); + } else if (ares == DW_DLV_ERROR) { + return ares; + } /* no entry: ok. */ + } else { + res = DW_DLV_ERROR; /* NO_ENTRY is impossible. */ + } + break; + + default: + /* surprising! An error? */ + + ; /* do nothing */ + } + dwarf_dealloc(dbg, attr, DW_DLA_ATTR); + + } else { + res = ares; + } + return res; +} + +/* + Return DW_DLV_OK if handling this went ok. +*/ +static int +handle_attr_locdesc(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attrnum, + Dwarf_Error * perr) +{ + int retval = DW_DLV_OK; + Dwarf_Attribute attr; + Dwarf_Locdesc *llbuf; + Dwarf_Signed i; + Dwarf_Off offset; + Dwarf_Loc *locp; + unsigned int entindx; + int res; + int ares; + + + ares = dwarf_attr(die, attrnum, &attr, perr); + if (ares == DW_DLV_OK) { + Dwarf_Half form; + int fres = dwarf_whatform(attr, &form, perr); + + if (fres == DW_DLV_OK) { + switch (form) { + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + /* must be location description */ + res = dwarf_attr_offset(die, attr, &offset, perr); + llbuf = 0; + if (res == DW_DLV_OK) { + Dwarf_Signed count; + int lres = + dwarf_loclist(attr, &llbuf, &count, perr); + if (lres != DW_DLV_OK) { + return lres; + } + if (count != 1) { + /* this cannot happen! */ + /* perr? */ + _dwarf_error(dbg, perr, + DW_DLE_LOCDESC_COUNT_WRONG); + retval = DW_DLV_ERROR; + return retval; + } + for (i = 0; i < count; ++i) { + unsigned int ents = llbuf[i].ld_cents; + + locp = llbuf[i].ld_s; + for (entindx = 0; entindx < ents; entindx++) { + Dwarf_Loc *llocp; + + llocp = locp + entindx; + if (llocp->lr_atom == DW_OP_addr) { + send_addr_note(DW_SECTION_INFO, offset + + llocp->lr_offset + 1 + /* The offset is the + offset of the atom, + ** and we know the + addr is 1 past it. */ + , llocp->lr_number); + } + } + } + + + if (count > 0) { + for (i = 0; i < count; ++i) { + dwarf_dealloc(dbg, llbuf[i].ld_s, + DW_DLA_LOC_BLOCK); + } + dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC); + } + } else { + retval = res; + } + break; + + default: + /* must be a const offset in debug_loc */ + ; /* do nothing */ + } + dwarf_dealloc(dbg, attr, DW_DLA_ATTR); + } /* else error or no entry */ + retval = fres; + } else { + retval = ares; + } + return retval; +} + +/* + Return DW_DLV_OK, or DW_DLV_ERROR + + Handle the addrs in a single die. +*/ +static int +process_this_die_attrs(Dwarf_Debug dbg, Dwarf_Die newdie, int *errval) +{ + Dwarf_Error err; + Dwarf_Half i; + Dwarf_Half newattrnum; + int res; + int tres; + Dwarf_Half ltag; + + Dwarf_Off doff; + int doffres = dwarf_dieoffset(newdie, &doff, &err); + + if (doffres != DW_DLV_OK) { + if (doffres == DW_DLV_ERROR) { + *errval = (int) dwarf_errno(err); + } + return doffres; + } + tres = dwarf_tag(newdie, <ag, &err); + if (tres != DW_DLV_OK) { + return tres; + } + if (DW_TAG_compile_unit == ltag) { + /* because of the way the dwarf_line code works, we do lines + only per compile unit. This may turn out to be wrong if + we have lines left unconnected to a CU. of course such + lines will not, at present, be used by gnome. This is + not ideal as coded due to the dwarf_line.c issue. */ + int lres; + + lres = handle_debug_line(dbg, newdie, send_addr_note, errval); + if (lres == DW_DLV_ERROR) { + return lres; + } + } + + for (i = 0; i < sizeof(might_have_addr) / sizeof(int); i++) { + int resattr; + Dwarf_Bool hasattr; + + newattrnum = might_have_addr[i]; + err = 0; + resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err); + if (DW_DLV_OK == resattr) { + if (hasattr) { + res = handle_attr_addr(dbg, newdie, newattrnum, &err); + if (res != DW_DLV_OK) { + *errval = (int) dwarf_errno(err); + return DW_DLV_ERROR; + } + } + } else { + if (resattr == DW_DLV_ERROR) { + *errval = (int) dwarf_errno(err); + return resattr; + } + } + } + for (i = 0; i < sizeof(might_have_locdesc) / sizeof(int); i++) { + int resattr; + Dwarf_Bool hasattr; + + newattrnum = might_have_locdesc[i]; + err = 0; + resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err); + if (DW_DLV_OK == resattr) { + if (hasattr) { + res = + handle_attr_locdesc(dbg, newdie, newattrnum, &err); + if (res != DW_DLV_OK) { + *errval = (int) dwarf_errno(err); + return DW_DLV_ERROR; + } + } + } else { + if (resattr == DW_DLV_ERROR) { + *errval = (int) dwarf_errno(err); + return resattr; + } + } + } + + return DW_DLV_OK; +} + +/* + Handle siblings as a list, + Do children by recursing. + Effectively this is walking the tree preorder. + + This dealloc's any die passed to it, so the + caller should not do that dealloc. + It seems more logical to have the one causing + the alloc to do the dealloc, but that way this + routine became a mess. + +*/ +static int +do_this_die_and_dealloc(Dwarf_Debug dbg, Dwarf_Die die, int *errval) +{ + + Dwarf_Die prevdie = 0; + Dwarf_Die newdie = die; + Dwarf_Error err = 0; + int res = 0; + int sibres = DW_DLV_OK; + int tres = DW_DLV_OK; + Dwarf_Die sibdie; + + while (sibres == DW_DLV_OK) { + Dwarf_Die ch_die; + + + res = process_this_die_attrs(dbg, newdie, errval); + switch (res) { + case DW_DLV_OK: + break; + case DW_DLV_NO_ENTRY: + break; + default: + case DW_DLV_ERROR: + if (prevdie) { + dwarf_dealloc(dbg, prevdie, DW_DLA_DIE); + prevdie = 0; + } + return DW_DLV_ERROR; + } + + tres = dwarf_child(newdie, &ch_die, &err); + + if (tres == DW_DLV_OK) { + res = do_this_die_and_dealloc(dbg, ch_die, errval); + switch (res) { + case DW_DLV_OK: + break; + case DW_DLV_NO_ENTRY: + break; + default: + case DW_DLV_ERROR: + if (prevdie) { + dwarf_dealloc(dbg, prevdie, DW_DLA_DIE); + prevdie = 0; + } + return DW_DLV_ERROR; + } + } else if (tres == DW_DLV_ERROR) { + /* An error! */ + *errval = (int) dwarf_errno(err); + if (prevdie) { + dwarf_dealloc(dbg, prevdie, DW_DLA_DIE); + prevdie = 0; + } + dwarf_dealloc(dbg, err, DW_DLA_ERROR); + return DW_DLV_ERROR; + } /* else was NO ENTRY */ + prevdie = newdie; + sibdie = 0; + sibres = dwarf_siblingof(dbg, newdie, &sibdie, &err); + if (prevdie) { + dwarf_dealloc(dbg, prevdie, DW_DLA_DIE); + prevdie = 0; + } + newdie = sibdie; + + } + if (sibres == DW_DLV_NO_ENTRY) { + return DW_DLV_OK; + } + /* error. */ + *errval = (int) dwarf_errno(err); + if (prevdie) { + dwarf_dealloc(dbg, prevdie, DW_DLA_DIE); + prevdie = 0; + } + dwarf_dealloc(dbg, err, DW_DLA_ERROR); + return DW_DLV_ERROR; + +} + + +static int +handle_debug_frame(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, + int *errval) +{ + int retval = DW_DLV_OK; + int res; + Dwarf_Error err; + Dwarf_Addr *addrlist; + Dwarf_Off *offsetlist; + Dwarf_Signed count; + int i; + + res = + _dwarf_frame_address_offsets(dbg, &addrlist, &offsetlist, + &count, &err); + if (res == DW_DLV_OK) { + for (i = 0; i < count; i++) { + cb_func(DW_SECTION_FRAME, offsetlist[i], addrlist[i]); + } + dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR); + dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR); + } else if (res == DW_DLV_NO_ENTRY) { + retval = res; + } else { + *errval = (int) dwarf_errno(err); + retval = DW_DLV_ERROR; + } + return retval; + +} +static int +handle_debug_aranges(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, + int *errval) +{ + int retval = DW_DLV_OK; + Dwarf_Error err; + Dwarf_Addr *aranges; + Dwarf_Signed count; + int indx; + Dwarf_Off *offsets; + + retval = + _dwarf_get_aranges_addr_offsets(dbg, &aranges, &offsets, &count, + &err); + if (retval == DW_DLV_OK) { + if (count == 0) { + retval = DW_DLV_NO_ENTRY; + } else { + for (indx = 0; indx < count; indx++) { + cb_func(DW_SECTION_ARANGES, offsets[indx], + aranges[indx]); + } + } + dwarf_dealloc(dbg, aranges, DW_DLA_ADDR); + dwarf_dealloc(dbg, offsets, DW_DLA_ADDR); + } else if (retval == DW_DLV_NO_ENTRY) { + ; /* do nothing */ + } else { + *errval = (int) dwarf_errno(err); + retval = DW_DLV_ERROR; + } + return retval; +} +static int +handle_debug_line(Dwarf_Debug dbg, Dwarf_Die cu_die, + Dwarf_addr_callback_func cb_func, int *errval) +{ + int retval = DW_DLV_OK; + int res; + Dwarf_Error err; + Dwarf_Addr *addrlist; + Dwarf_Off *offsetlist; + Dwarf_Unsigned count; + Dwarf_Unsigned i; + + res = + _dwarf_line_address_offsets(dbg, cu_die, &addrlist, &offsetlist, + &count, &err); + if (res == DW_DLV_OK) { + for (i = 0; i < count; i++) { + cb_func(DW_SECTION_LINE, offsetlist[i], addrlist[i]); + + } + dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR); + dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR); + } else if (res == DW_DLV_NO_ENTRY) { + retval = res; + } else { + *errval = (int) dwarf_errno(err); + retval = DW_DLV_ERROR; + } + return retval; +} + +/* + We need to add support for this. Currently we do not + generate this section. + FIX! +*/ +static int +handle_debug_loc(void) +{ + int retval = DW_DLV_NO_ENTRY; + + return retval; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_alloc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_alloc.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1240 @@ +/* + + Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + +#undef DEBUG + +#include "config.h" +#include "dwarf_incl.h" +#include + +#include +#include +#include "malloc_check.h" + +/* + These files are included to get the sizes + of structs to set the ah_bytes_one_struct field + of the Dwarf_Alloc_Hdr_s structs for each + allocation type. +*/ +#include "dwarf_line.h" +#include "dwarf_global.h" +#include "dwarf_arange.h" +#include "dwarf_abbrev.h" +#include "dwarf_die_deliv.h" +#include "dwarf_frame.h" +#include "dwarf_loc.h" +#include "dwarf_funcs.h" +#include "dwarf_types.h" +#include "dwarf_vars.h" +#include "dwarf_weaks.h" + +static void _dwarf_free_special_error(Dwarf_Ptr space); + +#ifdef DWARF_SIMPLE_MALLOC +static void _dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg, + Dwarf_Ptr addr, + unsigned long size, + short alloc_type); +static void _dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg, + Dwarf_Ptr space, + short alloc_type); +void _dwarf_simple_malloc_botch(int err); + +#endif /* DWARF_SIMPLE_MALLOC */ + + + + +/* + This macro adds the size of a pointer to the size of a + struct that is given to it. It rounds up the size to + be a multiple of the size of a pointer. This is done + so that every struct returned by _dwarf_get_alloc() + can be preceded by a pointer to the chunk it came from. + Before allocating, it checks if the size of struct is less than + the size of a pointer. If yes, it returns the size + of 2 pointers. The returned size should be at least + the size of 2 pointers, since the first points to the + chunk the struct was allocated from, and the second + is used to link the free list. + + We want DW_RESERVE to be at least the size of + a long long and at least the size of a pointer because + our struct has a long long and we want that aligned right. + Now Standard C defines long long as 8 bytes, so lets + make that standard. It will become unworkable when + long long or pointer grows beyound 8 bytes. + Unclear what to do with wierd requirements, like + 36 bit pointers. + + +*/ +#define DW_RESERVE 8 + +/* Round size up to the next multiple of DW_RESERVE bytes +*/ +#define ROUND_SIZE(inputsize) \ + (((inputsize) % (DW_RESERVE)) == 0 ? \ + (inputsize): \ + ((inputsize) + \ + (DW_RESERVE) - ((inputsize) % (DW_RESERVE)) )) + +#define ROUND_SIZE_WITH_POINTER(i_size) (ROUND_SIZE(i_size) + DW_RESERVE) + +/* SMALL_ALLOC is for trivia where allocation is a waste. + Things that should be removed, really. */ +#define SMALL_ALLOC 2 + +/* BASE_ALLOC is where a basic allocation makes sense, but 'not too large'. + No thorough evaluation of this value has been done, though + it was found wasteful of memory to have BASE_ALLOC be as large as + BIG_ALLOC. */ +#define BASE_ALLOC 64 + +/* BIG_ALLOC is where a larger-than-BASE_ALLOC + allocation makes sense, but still 'not too large'. + No thorough evaluation of this value has been done. */ +#define BIG_ALLOC 128 + +/* This translates into de_alloc_hdr index +** the 0,1,1 entries are special: they don't use the +** table values at all. +** Rearranging the DW_DLA values would break binary compatibility +** so that is not an option. +*/ +struct ial_s { + int ia_al_num; /* Index into de_alloc_hdr table. */ + + /* In bytes, one struct instance. This does not account for extra + space needed per block, but that (DW_RESERVE) will be added in + later where it is needed (DW_RESERVE space never added in here). + */ + int ia_struct_size; + + + /* Number of instances per alloc block. MUST be > 0. */ + int ia_base_count; + + int (*specialconstructor) (Dwarf_Debug, void *); + void (*specialdestructor) (void *); +}; + +static const +struct ial_s index_into_allocated[ALLOC_AREA_INDEX_TABLE_MAX] = { + {0, 1, 1, 0, 0}, /* none */ + {0, 1, 1, 0, 0}, /* 1 DW_DLA_STRING */ + {1, sizeof(Dwarf_Loc), BASE_ALLOC, 0, 0} + , /* 2 DW_DLA_LOC */ + {2, sizeof(Dwarf_Locdesc), BASE_ALLOC, 0, 0} + , /* 3 DW_DLA_LOCDESC */ + {0, 1, 1, 0, 0} + , /* not used *//* 4 DW_DLA_ELLIST */ + {0, 1, 1, 0, 0} + , /* not used *//* 5 DW_DLA_BOUNDS */ + {3, sizeof(Dwarf_Block), BASE_ALLOC, 0, 0} + , /* 6 DW_DLA_BLOCK */ + {0, 1, 1, 0, 0} + , /* the actual dwarf_debug structure *//* 7 DW_DLA_DEBUG */ + {4, sizeof(struct Dwarf_Die_s), BIG_ALLOC, 0, 0}, /* 8 DW_DLA_DIE + */ + {5, sizeof(struct Dwarf_Line_s), BIG_ALLOC, 0, 0}, /* 9 + DW_DLA_LINE */ + {6, sizeof(struct Dwarf_Attribute_s), BIG_ALLOC * 2, 0, 0}, + /* 10 DW_DLA_ATTR */ + {0, 1, 1, 0, 0}, /* not used *//* 11 DW_DLA_TYPE */ + {0, 1, 1, 0, 0}, /* not used *//* 12 DW_DLA_SUBSCR */ + {7, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 13 + DW_DLA_GLOBAL + */ + {8, sizeof(struct Dwarf_Error_s), BASE_ALLOC, 0, 0}, /* 14 + DW_DLA_ERROR + */ + {0, 1, 1, 0, 0}, /* 15 DW_DLA_LIST */ + {0, 1, 1, 0, 0}, /* not used *//* 16 DW_DLA_LINEBUF */ + {9, sizeof(struct Dwarf_Arange_s), BASE_ALLOC, 0, 0}, /* 17 + DW_DLA_ARANGE + */ + {10, sizeof(struct Dwarf_Abbrev_s), BIG_ALLOC, 0, 0}, /* 18 + DW_DLA_ABBREV + */ + {11, sizeof(Dwarf_Frame_Op), BIG_ALLOC, 0, 0} + , /* 19 DW_DLA_FRAME_OP */ + {12, sizeof(struct Dwarf_Cie_s), BASE_ALLOC, 0, 0}, /* 20 + DW_DLA_CIE */ + {13, sizeof(struct Dwarf_Fde_s), BASE_ALLOC, 0, 0}, /* 21 + DW_DLA_FDE */ + {0, 1, 1, 0, 0}, /* 22 DW_DLA_LOC_BLOCK */ + {0, 1, 1, 0, 0}, /* 23 DW_DLA_FRAME_BLOCK */ + {14, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 24 + DW_DLA_FUNC + UNUSED + */ + {15, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 25 + DW_DLA_TYPENAME + UNUSED */ + {16, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 26 + DW_DLA_VAR + UNUSED + */ + {17, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 27 + DW_DLA_WEAK + UNUSED + */ + {0, 1, 1, 0, 0}, /* 28 DW_DLA_ADDR */ + {18, sizeof(struct Dwarf_Abbrev_List_s), BIG_ALLOC, 0, 0}, + /* 29 DW_DLA_ABBREV_LIST */ + + {19, sizeof(struct Dwarf_Chain_s), BIG_ALLOC, 0, 0}, /* 30 + DW_DLA_CHAIN + */ + {20, sizeof(struct Dwarf_CU_Context_s), BASE_ALLOC, 0, 0}, + /* 31 DW_DLA_CU_CONTEXT */ + {21, sizeof(struct Dwarf_Frame_s), BASE_ALLOC, + _dwarf_frame_constructor, + _dwarf_frame_destructor}, /* 32 DW_DLA_FRAME */ + {22, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0}, + /* 33 DW_DLA_GLOBAL_CONTEXT */ + {23, sizeof(struct Dwarf_File_Entry_s), BASE_ALLOC, 0, 0}, /* 34 */ + /* 34 DW_DLA_FILE_ENTRY */ + {24, sizeof(struct Dwarf_Line_Context_s), BASE_ALLOC, 0, 0}, + /* 35 DW_DLA_LINE_CONTEXT */ + {25, sizeof(struct Dwarf_Loc_Chain_s), BASE_ALLOC, 0, 0}, /* 36 */ + /* 36 DW_DLA_LOC_CHAIN */ + + /* See use of ABBREV_HASH_TABLE_SIZE below for final dealloc. */ + {26, ABBREV_HASH_TABLE_SIZE * sizeof(struct Dwarf_Hash_Table_s), + BASE_ALLOC, 0, 0}, /* 37 */ + + + /* 37 DW_DLA_HASH_TABLE */ + +/* The following really use Global struct: used to be unique struct + per type, but now merged (11/99). The opaque types + are visible in the interface. The types for + DW_DLA_FUNC, + DW_DLA_TYPENAME, DW_DLA_VAR, DW_DLA_WEAK also use + the global types. + +*/ + {27, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0}, + /* 38 DW_DLA_FUNC_CONTEXT */ + {28, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0}, + /* 39 DW_DLA_TYPENAME_CONTEXT */ + {29, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0}, + /* 40 DW_DLA_VAR_CONTEXT */ + {30, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0}, + /* 41 DW_DLA_WEAK_CONTEXT */ + {31, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0}, + /* 42 DW_DLA_PUBTYPES_CONTEXT DWARF3 */ + +}; + +#ifndef DWARF_SIMPLE_MALLOC + +/* + This function is given a pointer to the header + structure that is used to allocate 1 struct of + the type given by alloc_type. It first checks + if a struct is available in its free list. If + not, it checks if 1 is available in its blob, + which is a chunk of memory that is reserved for + its use. If not, it malloc's a chunk. The + initial part of it is used to store the end + address of the chunk, and also to keep track + of the number of free structs in that chunk. + This information is used for freeing the chunk + when all the structs in it are free. + + Assume all input arguments have been validated. + + This function can be used only to allocate 1 + struct of the given type. + + It returns a pointer to the struct that the + user can use. It returns NULL only when it + is out of free structs, and cannot malloc + any more. The struct returned is zero-ed. + + A pointer to the chunk that the struct belongs + to is stored in the bytes preceding the + returned address. Since this pointer it + never overwritten, when a struct is allocated + from the free_list this pointer does not + have to be written. In the 2 other cases, + where the struct is allocated from a new + chunk, or the blob, a pointer to the chunk + is written. +*/ +static Dwarf_Ptr +_dwarf_find_memory(Dwarf_Alloc_Hdr alloc_hdr) +{ + /* Pointer to the struct allocated. */ + Dwarf_Small *ret_mem = 0; + + /* Pointer to info about chunks allocated. */ + Dwarf_Alloc_Area alloc_area; + + /* Size of chunk malloc'ed when no free structs left. */ + Dwarf_Signed mem_block_size; + + /* Pointer to block malloc'ed. */ + Dwarf_Small *mem_block; + + /* + Check the alloc_area from which the last allocation was made + (most recent new block). If that is not successful, then search + the list of alloc_area's from alloc_header. */ + alloc_area = alloc_hdr->ah_last_alloc_area; + if (alloc_area == NULL || alloc_area->aa_free_structs_in_chunk == 0) + for (alloc_area = alloc_hdr->ah_alloc_area_head; + alloc_area != NULL; alloc_area = alloc_area->aa_next) { + + if (alloc_area->aa_free_structs_in_chunk > 0) { + break; /* found a free entry! */ + } + + } + + if (alloc_area != NULL) { + alloc_area->aa_free_structs_in_chunk--; + + if (alloc_area->aa_free_list != NULL) { + ret_mem = alloc_area->aa_free_list; + + /* + Update the free list. The initial part of the struct is + used to hold a pointer to the next struct on the free + list. In this way, the free list chain is maintained at + 0 memory cost. */ + alloc_area->aa_free_list = + ((Dwarf_Free_List) ret_mem)->fl_next; + } else if (alloc_area->aa_blob_start < alloc_area->aa_blob_end) { + ret_mem = alloc_area->aa_blob_start; + + /* + Store pointer to chunk this struct belongs to in the + first few bytes. Return pointer to bytes after this + pointer storage. */ + *(Dwarf_Alloc_Area *) ret_mem = alloc_area; + ret_mem += DW_RESERVE; + + alloc_area->aa_blob_start += alloc_hdr->ah_bytes_one_struct; + } else { + /* else fall thru , though it should be impossible to fall + thru. And represents a disastrous programming error if + we get here. */ +#ifdef DEBUG + fprintf(stderr, "libdwarf Internal error start %x end %x\n", + (int) alloc_area->aa_blob_start, + (int) alloc_area->aa_blob_end); +#endif + } + } + + /* New memory has to malloc'ed since there are no free structs. */ + if (ret_mem == 0) { + Dwarf_Word rounded_area_hdr_size; + + alloc_hdr->ah_chunks_allocated++; + + { /* this nonsense avoids a warning */ + /* CONSTCOND would be better */ + unsigned long v = sizeof(struct Dwarf_Alloc_Area_s); + + rounded_area_hdr_size = ROUND_SIZE(v); + } + + /* + Allocate memory to contain the required number of structs + and the Dwarf_Alloc_Area_s to control it. */ + mem_block_size = alloc_hdr->ah_bytes_malloc_per_chunk + + rounded_area_hdr_size; + + mem_block = malloc(mem_block_size); + if (mem_block == NULL) { + return (NULL); + } + + + /* + Attach the Dwarf_Alloc_Area_s struct to the list of chunks + malloc'ed for this struct type. Also initialize the fields + of the Dwarf_Alloc_Area_s. */ + alloc_area = (Dwarf_Alloc_Area) mem_block; + alloc_area->aa_prev = 0; + if (alloc_hdr->ah_alloc_area_head != NULL) { + alloc_hdr->ah_alloc_area_head->aa_prev = alloc_area; + } + alloc_area->aa_free_list = 0; + alloc_area->aa_next = alloc_hdr->ah_alloc_area_head; + alloc_hdr->ah_alloc_area_head = alloc_area; + + alloc_area->aa_alloc_hdr = alloc_hdr; + alloc_area->aa_free_structs_in_chunk = + (Dwarf_Sword) alloc_hdr->ah_structs_per_chunk - 1; + if (alloc_area->aa_free_structs_in_chunk < 1) { + /* If we get here, there is a disastrous programming error + somewhere. */ +#ifdef DEBUG + fprintf(stderr, + "libdwarf Internal error: free structs in chunk %d\n", + (int) alloc_area->aa_free_structs_in_chunk); +#endif + return NULL; + } + + /* + The struct returned begins immediately after the + Dwarf_Alloc_Area_s struct. */ + ret_mem = mem_block + rounded_area_hdr_size; + alloc_area->aa_blob_start = + ret_mem + alloc_hdr->ah_bytes_one_struct; + alloc_area->aa_blob_end = mem_block + mem_block_size; + + /* + Store pointer to chunk this struct belongs to in the first + few bytes. Return pointer to bytes after this pointer + storage. */ + *(Dwarf_Alloc_Area *) ret_mem = alloc_area; + ret_mem += DW_RESERVE; + } + + alloc_hdr->ah_last_alloc_area = alloc_area; + alloc_hdr->ah_struct_user_holds++; + memset(ret_mem, 0, alloc_hdr->ah_bytes_one_struct - DW_RESERVE); + return (ret_mem); +} + +#endif /* ndef DWARF_SIMPLE_MALLOC */ + +/* + This function returns a pointer to a region + of memory. For alloc_types that are not + strings or lists of pointers, only 1 struct + can be requested at a time. This is indicated + by an input count of 1. For strings, count + equals the length of the string it will + contain, i.e it the length of the string + plus 1 for the terminating null. For lists + of pointers, count is equal to the number of + pointers. For DW_DLA_FRAME_BLOCK, and + DW_DLA_LOC_BLOCK allocation types also, count + is the count of the number of structs needed. + + This function cannot be used to allocate a + Dwarf_Debug_s struct. + +*/ +Dwarf_Ptr +_dwarf_get_alloc(Dwarf_Debug dbg, + Dwarf_Small alloc_type, Dwarf_Unsigned count) +{ + Dwarf_Alloc_Hdr alloc_hdr; + + Dwarf_Ptr ret_mem; + + Dwarf_Signed size = 0; + unsigned int index; + unsigned int type = alloc_type; + + if (dbg == NULL) { + return (NULL); + } + + if (type >= ALLOC_AREA_INDEX_TABLE_MAX) { + /* internal error */ + return NULL; + } + index = index_into_allocated[type].ia_al_num; + /* zero also illegal but not tested for */ + + /* If the Dwarf_Debug is not fully set up, we will get index 0 for + any type and must do something. 'Not fully set up' can only + happen for DW_DLA_ERROR, I (davea) believe, and for that we call + special code here.. */ + + if (index == 0) { + if (alloc_type == DW_DLA_STRING) { + size = count; + } else if (alloc_type == DW_DLA_LIST) { + size = count * sizeof(Dwarf_Ptr); + } else if (alloc_type == DW_DLA_FRAME_BLOCK) { + size = count * sizeof(Dwarf_Frame_Op); + } else if (alloc_type == DW_DLA_LOC_BLOCK) { + size = count * sizeof(Dwarf_Loc); + } else if (alloc_type == DW_DLA_ADDR) { + size = count * + (sizeof(Dwarf_Addr) > sizeof(Dwarf_Off) ? + sizeof(Dwarf_Addr) : sizeof(Dwarf_Off)); + } else if (alloc_type == DW_DLA_ERROR) { + void *m = _dwarf_special_no_dbg_error_malloc(); + + dwarf_malloc_check_alloc_data(m, DW_DLA_ERROR); + return m; + + } else { + /* If we get here, there is a disastrous programming error + somewhere. */ +#ifdef DEBUG + fprintf(stderr, + "libdwarf Internal error: type %d unexpected\n", + (int) type); +#endif + } + } else { + alloc_hdr = &dbg->de_alloc_hdr[index]; + if (alloc_hdr->ah_bytes_one_struct > 0) { +#ifdef DWARF_SIMPLE_MALLOC + size = alloc_hdr->ah_bytes_one_struct; +#else + { + void *m = _dwarf_find_memory(alloc_hdr); + + dwarf_malloc_check_alloc_data(m, type); + if (index_into_allocated[type].specialconstructor) { + int res = + index_into_allocated[type]. + specialconstructor(dbg, m); + if (res != DW_DLV_OK) { + /* We leak what we allocated in + _dwarf_find_memory when constructor fails. */ + return NULL; + } + } + return m; + } +#endif + + } else { + /* Special case: should not really happen at all. */ + if (type == DW_DLA_ERROR) { + /* dwarf_init failure. Because dbg is incomplete we + won't use it to record the malloc. */ + void *m = _dwarf_special_no_dbg_error_malloc(); + + dwarf_malloc_check_alloc_data(m, DW_DLA_ERROR); + return m; + } else { + /* If we get here, there is a disastrous programming + error somewhere. */ +#ifdef DWARF_SIMPLE_MALLOC + _dwarf_simple_malloc_botch(3); +#endif +#ifdef DEBUG + fprintf(stderr, + "libdwarf Internal error: Type %d unexpected\n", + (int) type); +#endif + } + } + } + + ret_mem = malloc(size); +#ifdef DWARF_SIMPLE_MALLOC + _dwarf_simple_malloc_add_to_list(dbg, ret_mem, (unsigned long) size, + type); +#endif + if (ret_mem != NULL) + memset(ret_mem, 0, size); + + dwarf_malloc_check_alloc_data(ret_mem, type); + if (index_into_allocated[type].specialconstructor) { + int res = + index_into_allocated[type].specialconstructor(dbg, ret_mem); + if (res != DW_DLV_OK) { + /* We leak what we allocated in _dwarf_find_memory when + constructor fails. */ + return NULL; + } + } + + return (ret_mem); +} + + + +/* + This function is used to deallocate a region of memory + that was obtained by a call to _dwarf_get_alloc. Note + that though dwarf_dealloc() is a public function, + _dwarf_get_alloc() isn't. + + For lists, typically arrays of pointers, it is assumed + that the space was allocated by a direct call to malloc, + and so a straight free() is done. This is also the case + for variable length blocks such as DW_DLA_FRAME_BLOCK + and DW_DLA_LOC_BLOCK. + + For strings, the pointer might point to a string in + .debug_info or .debug_string. After this is checked, + and if found not to be the case, a free() is done, + again on the assumption that a malloc was used to + obtain the space. + + For other types of structs, a pointer to the chunk that + the struct was allocated out of, is present in the bytes + preceding the pointer passed in. For this chunk it is + checked whether all the structs in that chunk are now free. + If so, the entire chunk is free_ed. Otherwise, the space + is added to the free list for that chunk, and the free count + incremented. + + This function does not return anything. +*/ +void +dwarf_dealloc(Dwarf_Debug dbg, + Dwarf_Ptr space, Dwarf_Unsigned alloc_type) +{ + Dwarf_Alloc_Hdr alloc_hdr; + Dwarf_Alloc_Area alloc_area; + unsigned int type = alloc_type; + unsigned int index; + + if (space == NULL) { + return; + } + if (type == DW_DLA_ERROR) { + /* Get pointer to Dwarf_Alloc_Area this struct came from. See + dwarf_alloc.h ROUND_SIZE_WITH_POINTER stuff */ + alloc_area = + *(Dwarf_Alloc_Area *) ((char *) space - DW_RESERVE); + if (alloc_area == 0) { + /* This is the special case of a failed dwarf_init(). Also + (and more signficantly) there are a variety of other + situations where libdwarf does not *know* what dbg is + involved (because of a libdwarf-caller-error) so + libdwarf uses NULL as the dbg. Those too wind up here. */ + _dwarf_free_special_error(space); + dwarf_malloc_check_dealloc_data(space, type); + return; + } + + } + if (dbg == NULL) { + /* App error, or an app that failed to succeed in a + dwarf_init() call. */ + return; + } + if (type >= ALLOC_AREA_INDEX_TABLE_MAX) { + /* internal or user app error */ + return; + } + + index = index_into_allocated[type].ia_al_num; + /* + A string pointer may point into .debug_info or .debug_string. + Otherwise, they are directly malloc'ed. */ + dwarf_malloc_check_dealloc_data(space, type); + if (index == 0) { + if (type == DW_DLA_STRING) { + if ((Dwarf_Small *) space >= dbg->de_debug_info && + (Dwarf_Small *) space < + dbg->de_debug_info + dbg->de_debug_info_size) + return; + + if (dbg->de_debug_line != NULL && + (Dwarf_Small *) space >= dbg->de_debug_line && + (Dwarf_Small *) space < + dbg->de_debug_line + dbg->de_debug_line_size) + return; + + if (dbg->de_debug_pubnames != NULL && + (Dwarf_Small *) space >= dbg->de_debug_pubnames && + (Dwarf_Small *) space < + dbg->de_debug_pubnames + dbg->de_debug_pubnames_size) + return; + + if (dbg->de_debug_frame != NULL && + (Dwarf_Small *) space >= dbg->de_debug_frame && + (Dwarf_Small *) space < + dbg->de_debug_frame + dbg->de_debug_frame_size) + return; + + if (dbg->de_debug_str != NULL && + (Dwarf_Small *) space >= dbg->de_debug_str && + (Dwarf_Small *) space < + dbg->de_debug_str + dbg->de_debug_str_size) + return; + + if (dbg->de_debug_funcnames != NULL && + (Dwarf_Small *) space >= dbg->de_debug_funcnames && + (Dwarf_Small *) space < + dbg->de_debug_funcnames + dbg->de_debug_funcnames_size) + return; + + if (dbg->de_debug_typenames != NULL && + (Dwarf_Small *) space >= dbg->de_debug_typenames && + (Dwarf_Small *) space < + dbg->de_debug_typenames + dbg->de_debug_typenames_size) + return; + if (dbg->de_debug_pubtypes != NULL && + (Dwarf_Small *) space >= dbg->de_debug_pubtypes && + (Dwarf_Small *) space < + dbg->de_debug_pubtypes + dbg->de_debug_pubtypes_size) + return; + + if (dbg->de_debug_varnames != NULL && + (Dwarf_Small *) space >= dbg->de_debug_varnames && + (Dwarf_Small *) space < + dbg->de_debug_varnames + dbg->de_debug_varnames_size) + return; + + if (dbg->de_debug_weaknames != NULL && + (Dwarf_Small *) space >= dbg->de_debug_weaknames && + (Dwarf_Small *) space < + dbg->de_debug_weaknames + dbg->de_debug_weaknames_size) + return; + +#ifdef DWARF_SIMPLE_MALLOC + _dwarf_simple_malloc_delete_from_list(dbg, space, type); +#endif + free(space); + return; + } + + if (type == DW_DLA_LIST || + type == DW_DLA_FRAME_BLOCK || + type == DW_DLA_LOC_BLOCK || type == DW_DLA_ADDR) { + +#ifdef DWARF_SIMPLE_MALLOC + _dwarf_simple_malloc_delete_from_list(dbg, space, type); +#endif + free(space); + return; + } + /* else is an alloc type that is not used */ + /* app or internal error */ +#ifdef DWARF_SIMPLE_MALLOC + _dwarf_simple_malloc_botch(4); +#endif + return; + + } + if (index_into_allocated[type].specialdestructor) { + index_into_allocated[type].specialdestructor(space); + } +#ifdef DWARF_SIMPLE_MALLOC + _dwarf_simple_malloc_delete_from_list(dbg, space, type); + free(space); +#else /* !DWARF_SIMPLE_MALLOC */ + alloc_hdr = &dbg->de_alloc_hdr[index]; + + /* Get pointer to Dwarf_Alloc_Area this struct came from. See + dwarf_alloc.h ROUND_SIZE_WITH_POINTER stuff */ + alloc_area = *(Dwarf_Alloc_Area *) ((char *) space - DW_RESERVE); + + /* ASSERT: alloc_area != NULL If NULL we could abort, let it + coredump below, or return, pretending all is well. We go on, + letting program crash. Is caller error. */ + + /* + Check that the alloc_hdr field of the alloc_area we have is + pointing to the right alloc_hdr. This is used to catch use of + incorrect deallocation code by the user. */ + if (alloc_area->aa_alloc_hdr != alloc_hdr) { + /* If we get here, the user has called dwarf_dealloc wrongly or + there is some other disastrous error. By leaking mem here we + try to be safe... */ +#ifdef DEBUG + fprintf(stderr, + "libdwarf Internal error: type %d hdr mismatch %lx %lx " + "area ptr %lx\n", + (int) type, + (long) alloc_area->aa_alloc_hdr, + (long) alloc_hdr, (long) alloc_area); +#endif + return; + } + + alloc_hdr->ah_struct_user_holds--; + alloc_area->aa_free_structs_in_chunk++; + + /* + Give chunk back to malloc only when every struct is freed */ + if (alloc_area->aa_free_structs_in_chunk == + alloc_hdr->ah_structs_per_chunk) { + if (alloc_area->aa_prev != NULL) { + alloc_area->aa_prev->aa_next = alloc_area->aa_next; + } else { + alloc_hdr->ah_alloc_area_head = alloc_area->aa_next; + } + + if (alloc_area->aa_next != NULL) { + alloc_area->aa_next->aa_prev = alloc_area->aa_prev; + } + + alloc_hdr->ah_chunks_allocated--; + + if (alloc_area == alloc_hdr->ah_last_alloc_area) { + alloc_hdr->ah_last_alloc_area = NULL; + } + memset(alloc_area, 0, sizeof(*alloc_area)); + free(alloc_area); + } + + else { + ((Dwarf_Free_List) space)->fl_next = alloc_area->aa_free_list; + alloc_area->aa_free_list = space; + } +#endif /* !DWARF_SIMPLE_MALLOC */ +} + + +/* + Allocates space for a Dwarf_Debug_s struct, + since one does not exist. +*/ +Dwarf_Debug +_dwarf_get_debug(void + ) +{ + Dwarf_Debug dbg; + + dbg = (Dwarf_Debug) malloc(sizeof(struct Dwarf_Debug_s)); + if (dbg == NULL) + return (NULL); + else + memset(dbg, 0, sizeof(struct Dwarf_Debug_s)); + + return (dbg); +} + + +/* + Sets up the Dwarf_Debug_s struct for all the + allocation types currently defined. + Allocation types DW_DLA_STRING, DW_DLA_LIST, + DW_DLA_FRAME_BLOCK, DW_DLA_LOC_BLOCK are + malloc'ed directly. + + This routine should be called after _dwarf_setup(), + so that information about the sizes of the Dwarf + sections can be used to decide the number of + structs of each type malloc'ed. + + Also DW_DLA_ELLIST, DW_DLA_BOUNDS, DW_DLA_TYPE, + DW_DLA_SUBSCR, DW_DLA_LINEBUF allocation types + are currently not used. + The ah_bytes_one_struct and ah_structs_per_chunk fields for + these types have been set to 1 for efficiency + in dwarf_get_alloc(). + + Ah_alloc_num should be greater than 1 for all + types that are currently being used. + + Therefore, for these allocation types the + ah_bytes_one_struct, and ah_structs_per_chunk fields do not + need to be initialized. + + Being an internal routine, assume proper dbg. + + + + +*/ +/* +** Set up all the Dwarf_Alloc_Hdr records. +*/ + +Dwarf_Debug +_dwarf_setup_debug(Dwarf_Debug dbg) +{ + int i; + + for (i = 1; i <= MAX_DW_DLA; i++) { + const struct ial_s *ialp = &index_into_allocated[i]; + unsigned int hdr_index = ialp->ia_al_num; + Dwarf_Word str_size = ialp->ia_struct_size; + Dwarf_Word str_count = ialp->ia_base_count; + Dwarf_Word rnded_size = ROUND_SIZE_WITH_POINTER(str_size); + + Dwarf_Alloc_Hdr alloc_hdr = &dbg->de_alloc_hdr[hdr_index]; + + alloc_hdr->ah_bytes_one_struct = (Dwarf_Half) rnded_size; + + /* ah_structs_per_chunk must be >0 else we are in trouble */ + alloc_hdr->ah_structs_per_chunk = str_count; + alloc_hdr->ah_bytes_malloc_per_chunk = rnded_size * str_count; + } + return (dbg); +} + +/* + This function prints out the statistics + collected on allocation of memory chunks. +*/ +void +dwarf_print_memory_stats(Dwarf_Debug dbg) +{ + Dwarf_Alloc_Hdr alloc_hdr; + Dwarf_Shalf i; + + /* + Alloc types start at 1, not 0. Hence, the first NULL string, and + also a size of MAX_DW_DLA + 1. */ + char *alloc_type_name[MAX_DW_DLA + 1] = { + "", + "DW_DLA_STRING", + "DW_DLA_LOC", + "DW_DLA_LOCDESC", + "DW_DLA_ELLIST", + "DW_DLA_BOUNDS", + "DW_DLA_BLOCK", + "DW_DLA_DEBUG", + "DW_DLA_DIE", + "DW_DLA_LINE", + "DW_DLA_ATTR", + "DW_DLA_TYPE", + "DW_DLA_SUBSCR", + "DW_DLA_GLOBAL", + "DW_DLA_ERROR", + "DW_DLA_LIST", + "DW_DLA_LINEBUF", + "DW_DLA_ARANGE", + "DW_DLA_ABBREV", + "DW_DLA_FRAME_OP", + "DW_DLA_CIE", + "DW_DLA_FDE", + "DW_DLA_LOC_BLOCK", + "DW_DLA_FRAME_BLOCK", + "DW_DLA_FUNC", + "DW_DLA_TYPENAME", + "DW_DLA_VAR", + "DW_DLA_WEAK", + "DW_DLA_ADDR", + "DW_DLA_ABBREV_LIST", + "DW_DLA_CHAIN", + "DW_DLA_CU_CONTEXT", + "DW_DLA_FRAME", + "DW_DLA_GLOBAL_CONTEXT", + "DW_DLA_FILE_ENTRY", + "DW_DLA_LINE_CONTEXT", + "DW_DLA_LOC_CHAIN", + "DW_DLA_HASH_TABLE", + "DW_DLA_FUNC_CONTEXT", + "DW_DLA_TYPENAME_CONTEXT", + "DW_DLA_VAR_CONTEXT", + "DW_DLA_WEAK_CONTEXT" "DW_DLA_PUBTYPES_CONTEXT" + }; + + if (dbg == NULL) + return; + + printf("Size of Dwarf_Debug %4ld bytes\n", + (long) sizeof(*dbg)); + printf("Size of Dwarf_Alloc_Hdr_s %4ld bytes\n", + (long) sizeof(struct Dwarf_Alloc_Hdr_s)); + printf("size of Dwarf_Alloc_Area_s %4ld bytes\n", + (long) sizeof(struct Dwarf_Alloc_Area_s)); + + printf(" Alloc Type Curr Structs byt str\n"); + printf(" ---------- ---- ------- per per\n"); + for (i = 1; i <= MAX_DW_DLA; i++) { + int indx = index_into_allocated[i].ia_al_num; + + alloc_hdr = &dbg->de_alloc_hdr[indx]; + if (alloc_hdr->ah_bytes_one_struct != 1) { + printf("%2d %-25s %6d %8d %6d %6d\n", + (int) i, + alloc_type_name[i], + (int) alloc_hdr->ah_chunks_allocated, + (int) alloc_hdr->ah_struct_user_holds, + (int) alloc_hdr->ah_bytes_malloc_per_chunk, + (int) alloc_hdr->ah_structs_per_chunk); + } + } +} + + +#ifndef DWARF_SIMPLE_MALLOC +/* + This function is used to recursively + free the chunks still allocated, and + forward chained through the aa_next + pointer. +*/ +static void +_dwarf_recursive_free(Dwarf_Alloc_Area alloc_area) +{ + if (alloc_area->aa_next != NULL) { + _dwarf_recursive_free(alloc_area->aa_next); + } + + alloc_area->aa_next = 0; + alloc_area->aa_prev = 0; + free(alloc_area); +} +#endif + +/* + Used to free all space allocated for this Dwarf_Debug. + The caller should assume that the Dwarf_Debug pointer + itself is no longer valid upon return from this function. + + In case of difficulty, this function simply returns quietly. +*/ +int +_dwarf_free_all_of_one_debug(Dwarf_Debug dbg) +{ + Dwarf_Alloc_Hdr alloc_hdr; + Dwarf_Shalf i; + Dwarf_CU_Context context = 0; + Dwarf_CU_Context nextcontext = 0; + + if (dbg == NULL) + return (DW_DLV_ERROR); + + /* To do complete validation that we have no surprising missing or + erroneous deallocs it is advisable to do the dwarf_deallocs here + that are not things the user can otherwise request. + Housecleaning. */ + + for (context = dbg->de_cu_context_list; + context; context = nextcontext) { + Dwarf_Hash_Table hash_table = context->cc_abbrev_hash_table; + + /* A Hash Table is an array with ABBREV_HASH_TABLE_SIZE struct + Dwarf_Hash_Table_s entries in the array. */ + int hashnum = 0; + + for (; hashnum < ABBREV_HASH_TABLE_SIZE; ++hashnum) { + struct Dwarf_Abbrev_List_s *abbrev = 0; + struct Dwarf_Abbrev_List_s *nextabbrev = 0; + + abbrev = hash_table[hashnum].at_head; + for (; abbrev; abbrev = nextabbrev) { + nextabbrev = abbrev->ab_next; + dwarf_dealloc(dbg, abbrev, DW_DLA_ABBREV_LIST); + } + } + nextcontext = context->cc_next; + dwarf_dealloc(dbg, hash_table, DW_DLA_HASH_TABLE); + dwarf_dealloc(dbg, context, DW_DLA_CU_CONTEXT); + } + + /* Housecleaning done. Now really free all the space. */ + +#ifdef DWARF_SIMPLE_MALLOC + if (dbg->de_simple_malloc_base) { + struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base; + + while (smp) { + int i; + struct simple_malloc_record_s *prev_smp = 0; + + for (i = 0; i < smp->sr_used; ++i) { + struct simple_malloc_entry_s *cur; + + cur = &smp->sr_entry[i]; + if (cur->se_addr != 0) { + free(cur->se_addr); + cur->se_addr = 0; + } + } + prev_smp = smp; + smp = smp->sr_next; + free(prev_smp); + } + dbg->de_simple_malloc_base = 0; + } +#else + for (i = 1; i < ALLOC_AREA_REAL_TABLE_MAX; i++) { + int indx = i; + + alloc_hdr = &dbg->de_alloc_hdr[indx]; + if (alloc_hdr->ah_alloc_area_head != NULL) { + _dwarf_recursive_free(alloc_hdr->ah_alloc_area_head); + } + } + +#endif + + memset(dbg, 0, sizeof(*dbg)); /* Prevent accidental use later. */ + free(dbg); + return (DW_DLV_OK); +} + +/* A special case: we have no dbg, no alloc header etc. + So create something out of thin air that we can recognize + in dwarf_dealloc. + Something with the prefix (prefix space hidden from caller). + + Only applies to DW_DLA_ERROR, making up an error record. +*/ + +struct Dwarf_Error_s * +_dwarf_special_no_dbg_error_malloc(void) +{ + /* the union unused things are to guarantee proper alignment */ + union u { + Dwarf_Alloc_Area ptr_not_used; + struct Dwarf_Error_s base_not_used; + char data_space[sizeof(struct Dwarf_Error_s) + + (DW_RESERVE * 2)]; + }; + char *mem; + + mem = malloc(sizeof(union u)); + + if (mem == 0) { + return 0; + + } + memset(mem, 0, sizeof(union u)); + mem += DW_RESERVE; + return (struct Dwarf_Error_s *) mem; +} + +/* The free side of _dwarf_special_no_dbg_error_malloc() +*/ +static void +_dwarf_free_special_error(Dwarf_Ptr space) +{ + char *mem = (char *) space; + + mem -= DW_RESERVE; + free(mem); +} + + +#ifdef DWARF_SIMPLE_MALLOC +/* here solely for planting a breakpoint. */ +/* ARGSUSED */ +void +_dwarf_simple_malloc_botch(int err) +{ + fprintf(stderr,"simple malloc botch %d\n",err); +} +static void +_dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg, + Dwarf_Ptr addr, + unsigned long size, short alloc_type) +{ + struct simple_malloc_record_s *cur; + struct simple_malloc_entry_s *newentry; + + if (!dbg->de_simple_malloc_base) { + /* First entry to this routine. */ + dbg->de_simple_malloc_base = + malloc(sizeof(struct simple_malloc_record_s)); + if (!dbg->de_simple_malloc_base) { + _dwarf_simple_malloc_botch(7); + return; /* no memory, give up */ + } + memset(dbg->de_simple_malloc_base, + 0, sizeof(struct simple_malloc_record_s)); + } + cur = dbg->de_simple_malloc_base; + + if (cur->sr_used >= DSM_BLOCK_COUNT) { + /* better not be > than as that means chaos */ + + /* Create a new block to link at the head. */ + + struct simple_malloc_record_s *newblock = + malloc(sizeof(struct simple_malloc_record_s)); + if (!newblock) { + _dwarf_simple_malloc_botch(8); + return; /* Can do nothing, out of memory */ + } + memset(newblock, 0, sizeof(struct simple_malloc_record_s)); + /* Link the new block at the head of the chain, and make it + 'current' */ + dbg->de_simple_malloc_base = newblock; + newblock->sr_next = cur; + cur = newblock; + } + newentry = &cur->sr_entry[cur->sr_used]; + newentry->se_addr = addr; + newentry->se_size = size; + newentry->se_type = alloc_type; + ++cur->sr_used; +} + +/* + DWARF_SIMPLE_MALLOC: testing the hypothesis that the existing + malloc scheme here (see _dwarf_get_alloc()) is pointless complexity. + + DWARF_SIMPLE_MALLOC also makes it easy for a malloc-tracing + tool to verify libdwarf malloc has no botches (though of course + such does not test the complicated standard-libdwarf-alloc code). + + To properly answer the question, the simple-malloc allocate + and delete should be something other than a simple list. + Perhaps a heap, or perhaps a red-black tree. + +*/ +static void +_dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg, + Dwarf_Ptr space, short alloc_type) +{ + if (space == 0) { + _dwarf_simple_malloc_botch(6); + } + if (dbg->de_simple_malloc_base) { + struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base; + + while (smp) { + int i; + + for (i = 0; i < smp->sr_used; ++i) { + struct simple_malloc_entry_s *cur; + + cur = &smp->sr_entry[i]; + if (cur->se_addr == space) { + if (cur->se_type != alloc_type) { + _dwarf_simple_malloc_botch(0); + } + cur->se_addr = 0; + return; + } + } + smp = smp->sr_next; + } + } + /* Never found the space */ + _dwarf_simple_malloc_botch(1); + return; + +} +#endif diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_alloc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_alloc.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,167 @@ +/* + + Copyright (C) 2000,2005 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +Dwarf_Ptr _dwarf_get_alloc(Dwarf_Debug, Dwarf_Small, Dwarf_Unsigned); +Dwarf_Debug _dwarf_get_debug(void); +Dwarf_Debug _dwarf_setup_debug(Dwarf_Debug); +int _dwarf_free_all_of_one_debug(Dwarf_Debug); + +typedef struct Dwarf_Alloc_Area_s *Dwarf_Alloc_Area; +typedef struct Dwarf_Free_List_s *Dwarf_Free_List; + +#define ALLOC_AREA_INDEX_TABLE_MAX 43 +#define ALLOC_AREA_REAL_TABLE_MAX 32 + +/* + This struct is used to chain all the deallocated + structs on the free list of each chain. The structs + are chained internally, by using the memory they + contain. +*/ +struct Dwarf_Free_List_s { + Dwarf_Free_List fl_next; +}; + + +/* + This struct is used to manage all the chunks malloc'ed + for a particular alloc_type. Many of the fields are + initialized by dwarf_init(). +*/ +struct Dwarf_Alloc_Hdr_s { + + /* Count of actual number of structs user app holds pointers to + currently. */ + Dwarf_Sword ah_struct_user_holds; + + /* + Size of each struct that will be allocated for this alloc_type. + Initialized by dwarf_init(). */ + Dwarf_Half ah_bytes_one_struct; + + /* + Number of structs of this alloc_type that will be contained in + each chunk that is malloc'ed. Initialized by dwarf_init(). */ + Dwarf_Word ah_structs_per_chunk; + + /* + Number of bytes malloc'ed per chunk which is basically + (ah_bytes_one_struct+_DWARF_RESERVE) * ah_alloc_num. */ + Dwarf_Word ah_bytes_malloc_per_chunk; + + /* Count of chunks currently allocated for type. */ + Dwarf_Sword ah_chunks_allocated; + + /* + Points to a chain of Dwarf_Alloc_Area_s structs that represent + all the chunks currently allocated for the alloc_type. */ + Dwarf_Alloc_Area ah_alloc_area_head; + + /* Last Alloc Area that was allocated by malloc. The + free-space-search area looks here first and only if it is full + goes thru the list pointed to by ah_alloc_area_head. */ + Dwarf_Alloc_Area ah_last_alloc_area; +}; + + +/* + This struct is used to manage each chunk that is + malloc'ed for a particular alloc_type. For each + allocation type, the allocation header points to + a list of all the chunks malloc'ed for that type. +*/ +struct Dwarf_Alloc_Area_s { + + /* Points to the free list of structs in the chunk. */ + Dwarf_Ptr aa_free_list; + + /* + Count of the number of free structs in the chunk. This includes + both those on the free list, and in the blob. */ + Dwarf_Sword aa_free_structs_in_chunk; + + /* + Points to the first byte of the blob from which struct will be + allocated. A struct is put on the free_list only when it + dwarf_deallocated. Initial allocations are from the blob. */ + Dwarf_Small *aa_blob_start; + + /* Points just past the last byte of the blob. */ + Dwarf_Small *aa_blob_end; + + /* Points to alloc_hdr this alloc_area is linked to: The owner, in + other words. */ + Dwarf_Alloc_Hdr aa_alloc_hdr; + + /* + Used for chaining Dwarf_Alloc_Area_s atructs. Alloc areas are + doubly linked to enable deletion from the list in constant time. */ + Dwarf_Alloc_Area aa_next; + Dwarf_Alloc_Area aa_prev; +}; + +struct Dwarf_Error_s *_dwarf_special_no_dbg_error_malloc(void); + +#ifdef DWARF_SIMPLE_MALLOC +/* + DWARF_SIMPLE_MALLOC is for testing the hypothesis that the existing + complex malloc scheme in libdwarf is pointless complexity. + + DWARF_SIMPLE_MALLOC also makes it easy for a malloc-tracing + tool to verify libdwarf malloc has no botches (though of course + such does not test the complicated standard-libdwarf-alloc code). + +*/ + +struct simple_malloc_entry_s { + Dwarf_Small *se_addr; + unsigned long se_size; + short se_type; +}; +#define DSM_BLOCK_COUNT (1000) +#define DSM_BLOCK_SIZE (sizeof(struct simple_malloc_entry_s)*DSM_BLOCK_COUNT) + +/* we do this so dwarf_dealloc can really free everything */ +struct simple_malloc_record_s { + struct simple_malloc_record_s *sr_next; + int sr_used; + struct simple_malloc_entry_s sr_entry[DSM_BLOCK_COUNT]; +}; + + + +#endif /* DWARF_SIMPLE_MALLOC */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_arange.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_arange.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,649 @@ +/* + + Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + + + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_arange.h" +#include "dwarf_global.h" /* for _dwarf_fixup_* */ + + +/* + This function returns the count of the number of + aranges in the .debug_aranges section. It sets + aranges to point to a block of Dwarf_Arange's + describing the arange's. It returns DW_DLV_ERROR + on error. + + Must be identical in most aspects to + dwarf_get_aranges_addr_offsets! +*/ +int +dwarf_get_aranges(Dwarf_Debug dbg, + Dwarf_Arange ** aranges, + Dwarf_Signed * returned_count, Dwarf_Error * error) +{ + /* Sweeps the .debug_aranges section. */ + Dwarf_Small *arange_ptr = 0; + + /* + Start of arange header. Used for rounding offset of arange_ptr + to twice the tuple size. Libdwarf requirement. */ + Dwarf_Small *header_ptr = 0; + + + /* Version of .debug_aranges header. */ + Dwarf_Half version = 0; + + /* Offset of current set of aranges into .debug_info. */ + Dwarf_Off info_offset = 0; + + /* Size in bytes of addresses in target. */ + Dwarf_Small address_size = 0; + + /* Size in bytes of segment offsets in target. */ + Dwarf_Small segment_size = 0; + + Dwarf_Small remainder = 0; + + /* Count of total number of aranges. */ + Dwarf_Unsigned arange_count = 0; + + /* Start address of arange. */ + Dwarf_Addr range_address = 0; + + /* Length of arange. */ + Dwarf_Unsigned range_length = 0; + + Dwarf_Arange arange, *arange_block = 0; + + Dwarf_Unsigned i = 0; + + /* Used to chain Dwarf_Aranges structs. */ + Dwarf_Chain curr_chain = NULL; + Dwarf_Chain prev_chain = NULL; + Dwarf_Chain head_chain = NULL; + + int res = 0; + + /* ***** BEGIN CODE ***** */ + + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + + res = + _dwarf_load_section(dbg, + dbg->de_debug_aranges_index, + &dbg->de_debug_aranges, error); + if (res != DW_DLV_OK) { + return res; + } + + arange_ptr = dbg->de_debug_aranges; + do { + /* Length of current set of aranges. */ + Dwarf_Unsigned length; + Dwarf_Small *arange_ptr_past_end = 0; + + int local_length_size; + + /*REFERENCED*/ /* Not used in this instance of the + macro */ + int local_extension_size; + + header_ptr = arange_ptr; + + /* READ_AREA_LENGTH updates arange_ptr for consumed bytes */ + READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, + arange_ptr, local_length_size, + local_extension_size); + arange_ptr_past_end = arange_ptr + length; + + + READ_UNALIGNED(dbg, version, Dwarf_Half, + arange_ptr, sizeof(Dwarf_Half)); + arange_ptr += sizeof(Dwarf_Half); + length = length - sizeof(Dwarf_Half); + if (version != CURRENT_VERSION_STAMP) { + _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); + return (DW_DLV_ERROR); + } + + READ_UNALIGNED(dbg, info_offset, Dwarf_Off, + arange_ptr, local_length_size); + arange_ptr += local_length_size; + length = length - local_length_size; + if (info_offset >= dbg->de_debug_info_size) { + FIX_UP_OFFSET_IRIX_BUG(dbg, info_offset, + "arange info offset.a"); + if (info_offset >= dbg->de_debug_info_size) { + _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); + return (DW_DLV_ERROR); + } + } + + address_size = *(Dwarf_Small *) arange_ptr; + if (address_size != dbg->de_pointer_size) { + /* Internal error of some kind */ + _dwarf_error(dbg, error, DW_DLE_BADBITC); + return (DW_DLV_ERROR); + } + arange_ptr = arange_ptr + sizeof(Dwarf_Small); + length = length - sizeof(Dwarf_Small); + + segment_size = *(Dwarf_Small *) arange_ptr; + arange_ptr = arange_ptr + sizeof(Dwarf_Small); + length = length - sizeof(Dwarf_Small); + if (segment_size != 0) { + _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD); + return (DW_DLV_ERROR); + } + + /* Round arange_ptr offset to next multiple of address_size. */ + remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) % + (2 * address_size); + if (remainder != 0) { + arange_ptr = arange_ptr + (2 * address_size) - remainder; + length = length - ((2 * address_size) - remainder); + } + + do { + READ_UNALIGNED(dbg, range_address, Dwarf_Addr, + arange_ptr, address_size); + arange_ptr += address_size; + length = length - address_size; + + READ_UNALIGNED(dbg, range_length, Dwarf_Unsigned, + arange_ptr, address_size); + arange_ptr += address_size; + length = length - address_size; + + if (range_address != 0 || range_length != 0) { + + arange = (Dwarf_Arange) + _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); + if (arange == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + arange->ar_address = range_address; + arange->ar_length = range_length; + arange->ar_info_offset = info_offset; + arange->ar_dbg = dbg; + arange_count++; + + curr_chain = (Dwarf_Chain) + _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (curr_chain == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + curr_chain->ch_item = arange; + if (head_chain == NULL) + head_chain = prev_chain = curr_chain; + else { + prev_chain->ch_next = curr_chain; + prev_chain = curr_chain; + } + } + } while (range_address != 0 || range_length != 0); + + /* A compiler could emit some padding bytes here. dwarf2/3 + (dwarf3 draft8 sec 7.20) does not clearly make extra padding + bytes illegal. */ + if (arange_ptr_past_end < arange_ptr) { + _dwarf_error(dbg, error, DW_DLE_ARANGE_LENGTH_BAD); + return (DW_DLV_ERROR); + } + /* For most compilers, arange_ptr == arange_ptr_past_end at + this point. But not if there were padding bytes */ + arange_ptr = arange_ptr_past_end; + + } while (arange_ptr < + dbg->de_debug_aranges + dbg->de_debug_aranges_size); + + if (arange_ptr != + dbg->de_debug_aranges + dbg->de_debug_aranges_size) { + _dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR); + return (DW_DLV_ERROR); + } + + arange_block = (Dwarf_Arange *) + _dwarf_get_alloc(dbg, DW_DLA_LIST, arange_count); + if (arange_block == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + curr_chain = head_chain; + for (i = 0; i < arange_count; i++) { + *(arange_block + i) = curr_chain->ch_item; + prev_chain = curr_chain; + curr_chain = curr_chain->ch_next; + dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); + } + + *aranges = arange_block; + *returned_count = (arange_count); + return DW_DLV_OK; +} + +/* + This function returns DW_DLV_OK if it succeeds + and DW_DLV_ERR or DW_DLV_OK otherwise. + count is set to the number of addresses in the + .debug_aranges section. + For each address, the corresponding element in + an array is set to the address itself(aranges) and + the section offset (offsets). + Must be identical in most aspects to + dwarf_get_aranges! +*/ +int +_dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg, + Dwarf_Addr ** addrs, + Dwarf_Off ** offsets, + Dwarf_Signed * count, + Dwarf_Error * error) +{ + /* Sweeps the .debug_aranges section. */ + Dwarf_Small *arange_ptr = 0; + Dwarf_Small *arange_start_ptr = 0; + + /* + Start of arange header. Used for rounding offset of arange_ptr + to twice the tuple size. Libdwarf requirement. */ + Dwarf_Small *header_ptr = 0; + + /* Length of current set of aranges. */ + Dwarf_Unsigned length = 0; + + /* Version of .debug_aranges header. */ + Dwarf_Half version = 0; + + /* Offset of current set of aranges into .debug_info. */ + Dwarf_Off info_offset = 0; + + /* Size in bytes of addresses in target. */ + Dwarf_Small address_size = 0; + + /* Size in bytes of segment offsets in target. */ + Dwarf_Small segment_size = 0; + + Dwarf_Small remainder = 0; + + /* Count of total number of aranges. */ + Dwarf_Unsigned arange_count = 0; + + /* Start address of arange. */ + Dwarf_Addr range_address = 0; + + /* Length of arange. */ + Dwarf_Unsigned range_length = 0; + + Dwarf_Arange arange = 0; + + Dwarf_Unsigned i = 0; + + /* Used to chain Dwarf_Aranges structs. */ + Dwarf_Chain curr_chain = NULL; + Dwarf_Chain prev_chain = NULL; + Dwarf_Chain head_chain = NULL; + + Dwarf_Addr *arange_addrs = 0; + Dwarf_Off *arange_offsets = 0; + + int res = 0; + + /* ***** BEGIN CODE ***** */ + + if (error != NULL) + *error = NULL; + + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + + res = + _dwarf_load_section(dbg, + dbg->de_debug_aranges_index, + &dbg->de_debug_aranges, error); + if (res != DW_DLV_OK) { + return res; + } + + arange_ptr = dbg->de_debug_aranges; + do { + int local_length_size; + + /*REFERENCED*/ /* not used in this instance of the + macro */ + int local_extension_size; + + header_ptr = arange_ptr; + + + /* READ_AREA_LENGTH updates arange_ptr for consumed bytes */ + READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, + arange_ptr, local_length_size, + local_extension_size); + + + READ_UNALIGNED(dbg, version, Dwarf_Half, + arange_ptr, sizeof(Dwarf_Half)); + arange_ptr += sizeof(Dwarf_Half); + length = length - sizeof(Dwarf_Half); + if (version != CURRENT_VERSION_STAMP) { + _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); + return (DW_DLV_ERROR); + } + + READ_UNALIGNED(dbg, info_offset, Dwarf_Off, + arange_ptr, local_length_size); + arange_ptr += local_length_size; + length = length - local_length_size; + if (info_offset >= dbg->de_debug_info_size) { + FIX_UP_OFFSET_IRIX_BUG(dbg, info_offset, + "arange info offset.b"); + if (info_offset >= dbg->de_debug_info_size) { + + _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); + return (DW_DLV_ERROR); + } + } + + address_size = *(Dwarf_Small *) arange_ptr; + arange_ptr = arange_ptr + sizeof(Dwarf_Small); + length = length - sizeof(Dwarf_Small); + + segment_size = *(Dwarf_Small *) arange_ptr; + arange_ptr = arange_ptr + sizeof(Dwarf_Small); + length = length - sizeof(Dwarf_Small); + if (segment_size != 0) { + _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD); + return (DW_DLV_ERROR); + } + + /* Round arange_ptr offset to next multiple of address_size. */ + remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) % + (2 * address_size); + if (remainder != 0) { + arange_ptr = arange_ptr + (2 * address_size) - remainder; + length = length - ((2 * address_size) - remainder); + } + + do { + arange_start_ptr = arange_ptr; + READ_UNALIGNED(dbg, range_address, Dwarf_Addr, + arange_ptr, dbg->de_pointer_size); + arange_ptr += dbg->de_pointer_size; + length = length - dbg->de_pointer_size; + + READ_UNALIGNED(dbg, range_length, Dwarf_Unsigned, + arange_ptr, local_length_size); + arange_ptr += local_length_size; + length = length - local_length_size; + + if (range_address != 0 || range_length != 0) { + + arange = (Dwarf_Arange) + _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); + if (arange == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + arange->ar_address = range_address; + arange->ar_length = range_length; + arange->ar_info_offset = + arange_start_ptr - dbg->de_debug_aranges; + arange->ar_dbg = dbg; + arange_count++; + + curr_chain = (Dwarf_Chain) + _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (curr_chain == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + curr_chain->ch_item = arange; + if (head_chain == NULL) + head_chain = prev_chain = curr_chain; + else { + prev_chain->ch_next = curr_chain; + prev_chain = curr_chain; + } + } + } while (range_address != 0 || range_length != 0); + + if (length != 0) { + _dwarf_error(dbg, error, DW_DLE_ARANGE_LENGTH_BAD); + return (DW_DLV_ERROR); + } + + } while (arange_ptr < + dbg->de_debug_aranges + dbg->de_debug_aranges_size); + + if (arange_ptr != + dbg->de_debug_aranges + dbg->de_debug_aranges_size) { + _dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR); + return (DW_DLV_ERROR); + } + + arange_addrs = (Dwarf_Addr *) + _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); + if (arange_addrs == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + arange_offsets = (Dwarf_Off *) + _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); + if (arange_offsets == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + curr_chain = head_chain; + for (i = 0; i < arange_count; i++) { + Dwarf_Arange ar = curr_chain->ch_item; + + arange_addrs[i] = ar->ar_address; + arange_offsets[i] = ar->ar_info_offset; + prev_chain = curr_chain; + curr_chain = curr_chain->ch_next; + dwarf_dealloc(dbg, ar, DW_DLA_ARANGE); + dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); + } + *count = arange_count; + *offsets = arange_offsets; + *addrs = arange_addrs; + return (DW_DLV_OK); +} + + +/* + This function takes a pointer to a block + of Dwarf_Arange's, and a count of the + length of the block. It checks if the + given address is within the range of an + address range in the block. If yes, it + returns the appropriate Dwarf_Arange. + Otherwise, it returns DW_DLV_ERROR. +*/ +int +dwarf_get_arange(Dwarf_Arange * aranges, + Dwarf_Unsigned arange_count, + Dwarf_Addr address, + Dwarf_Arange * returned_arange, Dwarf_Error * error) +{ + Dwarf_Arange curr_arange; + Dwarf_Unsigned i; + + if (aranges == NULL) { + _dwarf_error(NULL, error, DW_DLE_ARANGES_NULL); + return (DW_DLV_ERROR); + } + + for (i = 0; i < arange_count; i++) { + curr_arange = *(aranges + i); + if (address >= curr_arange->ar_address && + address < + curr_arange->ar_address + curr_arange->ar_length) { + *returned_arange = curr_arange; + return (DW_DLV_OK); + } + } + + return (DW_DLV_NO_ENTRY); +} + + +/* + This function takes an Dwarf_Arange, + and returns the offset of the first + die in the compilation-unit that the + arange belongs to. Returns DW_DLV_ERROR + on error. +*/ +int +dwarf_get_cu_die_offset(Dwarf_Arange arange, + Dwarf_Off * returned_offset, + Dwarf_Error * error) +{ + Dwarf_Debug dbg; + Dwarf_Off offset; + + if (arange == NULL) { + _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); + return (DW_DLV_ERROR); + } + + + dbg = arange->ar_dbg; + + + offset = arange->ar_info_offset; + if (!dbg->de_debug_info) { + int res = _dwarf_load_debug_info(dbg, error); + + if (res != DW_DLV_OK) { + return res; + } + } + + *returned_offset = offset + _dwarf_length_of_cu_header(dbg, offset); + return DW_DLV_OK; +} + +/* + This function takes an Dwarf_Arange, + and returns the offset of the CU header + in the compilation-unit that the + arange belongs to. Returns DW_DLV_ERROR + on error. +*/ +int +dwarf_get_arange_cu_header_offset(Dwarf_Arange arange, + Dwarf_Off * cu_header_offset_returned, + Dwarf_Error * error) +{ + if (arange == NULL) { + _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); + return (DW_DLV_ERROR); + } + + *cu_header_offset_returned = arange->ar_info_offset; + return DW_DLV_OK; +} + + + +/* + This function takes a Dwarf_Arange, and returns + true if it is not NULL. It also stores the start + address of the range in *start, the length of the + range in *length, and the offset of the first die + in the compilation-unit in *cu_die_offset. It + returns false on error. +*/ +int +dwarf_get_arange_info(Dwarf_Arange arange, + Dwarf_Addr * start, + Dwarf_Unsigned * length, + Dwarf_Off * cu_die_offset, Dwarf_Error * error) +{ + if (arange == NULL) { + _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); + return (DW_DLV_ERROR); + } + + if (start != NULL) + *start = arange->ar_address; + if (length != NULL) + *length = arange->ar_length; + if (cu_die_offset != NULL) { + Dwarf_Debug dbg = arange->ar_dbg; + Dwarf_Off offset = arange->ar_info_offset; + + if (!dbg->de_debug_info) { + int res = _dwarf_load_debug_info(dbg, error); + + if (res != DW_DLV_OK) { + return res; + } + } + + *cu_die_offset = + offset + _dwarf_length_of_cu_header(dbg, offset); + } + return (DW_DLV_OK); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_arange.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_arange.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,63 @@ +/* + + Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +/* This structure is used to read an arange into. */ +struct Dwarf_Arange_s { + + /* Starting address of the arange, ie low-pc. */ + Dwarf_Addr ar_address; + + /* Length of the arange. */ + Dwarf_Unsigned ar_length; + + /* + Offset into .debug_info of the start of the compilation-unit + containing this set of aranges. */ + Dwarf_Off ar_info_offset; + + /* Corresponding Dwarf_Debug. */ + Dwarf_Debug ar_dbg; +}; + + + +int + _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg, + Dwarf_Addr ** addrs, + Dwarf_Off ** offsets, + Dwarf_Signed * count, + Dwarf_Error * error); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_base_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_base_types.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,109 @@ +/* + + Copyright (C) 2000,2005 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "libdwarfdefs.h" + +#define true 1 +#define false 0 + +/* to identify a cie */ +#define DW_CIE_ID ~(0x0) +#define DW_CIE_VERSION 1 /* DWARF2 */ +#define DW_CIE_VERSION3 3 /* DWARF3 */ +#define ABBREV_HASH_TABLE_SIZE 10 + + +/* + These are allocation type codes for structs that + are internal to the Libdwarf Consumer library. +*/ +#define DW_DLA_ABBREV_LIST DW_DLA_ADDR + 1 +#define DW_DLA_CHAIN DW_DLA_ADDR + 2 +#define DW_DLA_CU_CONTEXT DW_DLA_ADDR + 3 +#define DW_DLA_FRAME DW_DLA_ADDR + 4 +#define DW_DLA_GLOBAL_CONTEXT DW_DLA_ADDR + 5 +#define DW_DLA_FILE_ENTRY DW_DLA_ADDR + 6 +#define DW_DLA_LINE_CONTEXT DW_DLA_ADDR + 7 +#define DW_DLA_LOC_CHAIN DW_DLA_ADDR + 8 +#define DW_DLA_HASH_TABLE DW_DLA_ADDR + 9 +#define DW_DLA_FUNC_CONTEXT DW_DLA_ADDR + 10 +#define DW_DLA_TYPENAME_CONTEXT DW_DLA_ADDR + 11 +#define DW_DLA_VAR_CONTEXT DW_DLA_ADDR + 12 +#define DW_DLA_WEAK_CONTEXT DW_DLA_ADDR + 13 +#define DW_DLA_PUBTYPES_CONTEXT DW_DLA_ADDR + 14 /* DWARF3 */ + +/* Maximum number of allocation types for allocation routines. */ +#define MAX_DW_DLA DW_DLA_PUBTYPES_CONTEXT + +/*Dwarf_Word is unsigned word usable for index, count in memory */ +/*Dwarf_Sword is signed word usable for index, count in memory */ +/* The are 32 or 64 bits depending if 64 bit longs or not, which +** fits the ILP32 and LP64 models +** These work equally well with ILP64. +*/ + +typedef unsigned long Dwarf_Word; +typedef signed long Dwarf_Sword; + +typedef signed char Dwarf_Sbyte; +typedef unsigned char Dwarf_Ubyte; +typedef signed short Dwarf_Shalf; +typedef Dwarf_Small *Dwarf_Byte_Ptr; + +/* these 2 are fixed sizes which must not vary with the +** ILP32/LP64 model. Between these two, stay at 32 bit. +*/ +typedef __uint32_t Dwarf_ufixed; +typedef __int32_t Dwarf_sfixed; + +/* + In various places the code mistakenly associates + forms 8 bytes long with Dwarf_Signed or Dwarf_Unsigned + This is not a very portable assumption. + The following should be used instead for 64 bit integers. +*/ +typedef __uint64_t Dwarf_ufixed64; +typedef __int64_t Dwarf_sfixed64; + + +typedef struct Dwarf_Abbrev_List_s *Dwarf_Abbrev_List; +typedef struct Dwarf_File_Entry_s *Dwarf_File_Entry; +typedef struct Dwarf_CU_Context_s *Dwarf_CU_Context; +typedef struct Dwarf_Hash_Table_s *Dwarf_Hash_Table; + + +typedef struct Dwarf_Alloc_Hdr_s *Dwarf_Alloc_Hdr; diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_die_deliv.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_die_deliv.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,816 @@ +/* + + Copyright (C) 2000,2001,2002,2003,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + + + +#include "config.h" +#include "dwarf_incl.h" +#ifdef HAVE_ELF_H +#include +#endif +#include +#include "dwarf_die_deliv.h" + + +/* + For a given Dwarf_Debug dbg, this function checks + if a CU that includes the given offset has been read + or not. If yes, it returns the Dwarf_CU_Context + for the CU. Otherwise it returns NULL. Being an + internal routine, it is assumed that a valid dbg + is passed. + + **This is a sequential search. May be too slow. + + If debug_info and debug_abbrev not loaded, this will + wind up returning NULL. So no need to load before calling + this. +*/ +static Dwarf_CU_Context +_dwarf_find_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset) +{ + Dwarf_CU_Context cu_context; + + if (offset >= dbg->de_info_last_offset) + return (NULL); + + if (dbg->de_cu_context != NULL && + dbg->de_cu_context->cc_next != NULL && + dbg->de_cu_context->cc_next->cc_debug_info_offset == offset) { + + return (dbg->de_cu_context->cc_next); + } + + if (dbg->de_cu_context != NULL && + dbg->de_cu_context->cc_debug_info_offset <= offset) { + + for (cu_context = dbg->de_cu_context; + cu_context != NULL; cu_context = cu_context->cc_next) { + + if (offset >= cu_context->cc_debug_info_offset && + offset < cu_context->cc_debug_info_offset + + cu_context->cc_length + cu_context->cc_length_size + + cu_context->cc_extension_size) { + + return (cu_context); + } + } + } + + for (cu_context = dbg->de_cu_context_list; + cu_context != NULL; cu_context = cu_context->cc_next) { + + if (offset >= cu_context->cc_debug_info_offset && + offset < cu_context->cc_debug_info_offset + + cu_context->cc_length + cu_context->cc_length_size + + cu_context->cc_extension_size) { + + return (cu_context); + } + } + + return (NULL); +} + + +/* + This routine checks the dwarf_offdie() list of + CU contexts for the right CU context. +*/ +static Dwarf_CU_Context +_dwarf_find_offdie_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset) +{ + Dwarf_CU_Context cu_context; + + for (cu_context = dbg->de_offdie_cu_context; + cu_context != NULL; cu_context = cu_context->cc_next) + + if (offset >= cu_context->cc_debug_info_offset && + offset < cu_context->cc_debug_info_offset + + cu_context->cc_length + cu_context->cc_length_size + + cu_context->cc_extension_size) + + return (cu_context); + + return (NULL); +} + + +/* + This function is used to create a CU Context for + a compilation-unit that begins at offset in + .debug_info. The CU Context is attached to the + list of CU Contexts for this dbg. It is assumed + that the CU at offset has not been read before, + and so do not call this routine before making + sure of this with _dwarf_find_CU_Context(). + Returns NULL on error. As always, being an + internal routine, assumes a good dbg. + + This function must always set a dwarf error code + before returning NULL. Always. +*/ +static Dwarf_CU_Context +_dwarf_make_CU_Context(Dwarf_Debug dbg, + Dwarf_Off offset, Dwarf_Error * error) +{ + Dwarf_CU_Context cu_context; + Dwarf_Unsigned length; + Dwarf_Signed abbrev_offset; + Dwarf_Byte_Ptr cu_ptr; + int local_extension_size = 0; + int local_length_size; + + cu_context = + (Dwarf_CU_Context) _dwarf_get_alloc(dbg, DW_DLA_CU_CONTEXT, 1); + if (cu_context == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (NULL); + } + cu_context->cc_dbg = dbg; + + cu_ptr = (Dwarf_Byte_Ptr) (dbg->de_debug_info + offset); + + /* READ_AREA_LENGTH updates cu_ptr for consumed bytes */ + READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, + cu_ptr, local_length_size, local_extension_size); + cu_context->cc_length_size = local_length_size; + cu_context->cc_extension_size = local_extension_size; + + + cu_context->cc_length = (Dwarf_Word) length; + + READ_UNALIGNED(dbg, cu_context->cc_version_stamp, Dwarf_Half, + cu_ptr, sizeof(Dwarf_Half)); + cu_ptr += sizeof(Dwarf_Half); + + READ_UNALIGNED(dbg, abbrev_offset, Dwarf_Signed, + cu_ptr, local_length_size); + cu_ptr += local_length_size; + cu_context->cc_abbrev_offset = (Dwarf_Sword) abbrev_offset; + + cu_context->cc_address_size = *(Dwarf_Small *) cu_ptr; + + if ((length < CU_VERSION_STAMP_SIZE + local_length_size + + CU_ADDRESS_SIZE_SIZE) || + (offset + length + local_length_size + + local_extension_size > dbg->de_debug_info_size)) { + + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); + _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR); + return (NULL); + } + + if (cu_context->cc_address_size != dbg->de_pointer_size) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); + _dwarf_error(dbg, error, DW_DLE_CU_ADDRESS_SIZE_BAD); + return (NULL); + } + + if (cu_context->cc_version_stamp != CURRENT_VERSION_STAMP + && cu_context->cc_version_stamp != CURRENT_VERSION_STAMP3 + && cu_context->cc_version_stamp != CURRENT_VERSION_STAMP4) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); + _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); + return (NULL); + } + + if (abbrev_offset >= dbg->de_debug_abbrev_size) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); + _dwarf_error(dbg, error, DW_DLE_ABBREV_OFFSET_ERROR); + return (NULL); + } + + cu_context->cc_abbrev_hash_table = + (Dwarf_Hash_Table) _dwarf_get_alloc(dbg, DW_DLA_HASH_TABLE, 1); + if (cu_context->cc_abbrev_hash_table == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (NULL); + } + + cu_context->cc_debug_info_offset = (Dwarf_Word) offset; + dbg->de_info_last_offset = + (Dwarf_Word) (offset + length + + local_extension_size + local_length_size); + + if (dbg->de_cu_context_list == NULL) { + dbg->de_cu_context_list = cu_context; + dbg->de_cu_context_list_end = cu_context; + } else { + dbg->de_cu_context_list_end->cc_next = cu_context; + dbg->de_cu_context_list_end = cu_context; + } + + return (cu_context); +} + + +/* + Returns offset of next compilation-unit thru next_cu_offset + pointer. + It basically sequentially moves from one + cu to the next. The current cu is recorded + internally by libdwarf. +*/ +int +dwarf_next_cu_header(Dwarf_Debug dbg, + Dwarf_Unsigned * cu_header_length, + Dwarf_Half * version_stamp, + Dwarf_Unsigned * abbrev_offset, + Dwarf_Half * address_size, + Dwarf_Unsigned * next_cu_offset, + Dwarf_Error * error) +{ + /* Offset for current and new CU. */ + Dwarf_Unsigned new_offset; + + /* CU Context for current CU. */ + Dwarf_CU_Context cu_context; + + /* ***** BEGIN CODE ***** */ + + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + /* + Get offset into .debug_info of next CU. If dbg has no context, + this has to be the first one. */ + if (dbg->de_cu_context == NULL) { + new_offset = 0; + if (!dbg->de_debug_info) { + int res = _dwarf_load_debug_info(dbg, error); + + if (res != DW_DLV_OK) { + return res; + } + } + + } else { + new_offset = dbg->de_cu_context->cc_debug_info_offset + + dbg->de_cu_context->cc_length + + dbg->de_cu_context->cc_length_size + + dbg->de_cu_context->cc_extension_size; + } + + /* + Check that there is room in .debug_info beyond the new offset + for at least a new cu header. If not, return 0 to indicate end + of debug_info section, and reset de_cu_debug_info_offset to + enable looping back through the cu's. */ + if ((new_offset + _dwarf_length_of_cu_header_simple(dbg)) >= + dbg->de_debug_info_size) { + dbg->de_cu_context = NULL; + return (DW_DLV_NO_ENTRY); + } + + /* Check if this CU has been read before. */ + cu_context = _dwarf_find_CU_Context(dbg, new_offset); + + /* If not, make CU Context for it. */ + if (cu_context == NULL) { + cu_context = _dwarf_make_CU_Context(dbg, new_offset, error); + if (cu_context == NULL) { + /* Error if CU Context could not be made. Since + _dwarf_make_CU_Context has already registered an error + we do not do that here: we let the lower error pass + thru. */ + return (DW_DLV_ERROR); + } + } + + dbg->de_cu_context = cu_context; + + if (cu_header_length != NULL) + *cu_header_length = cu_context->cc_length; + + if (version_stamp != NULL) + *version_stamp = cu_context->cc_version_stamp; + + if (abbrev_offset != NULL) + *abbrev_offset = cu_context->cc_abbrev_offset; + + if (address_size != NULL) + *address_size = cu_context->cc_address_size; + + new_offset = new_offset + cu_context->cc_length + + cu_context->cc_length_size + cu_context->cc_extension_size; + *next_cu_offset = new_offset; + return (DW_DLV_OK); +} + + +/* + This function does two slightly different things + depending on the input flag want_AT_sibling. If + this flag is true, it checks if the input die has + a DW_AT_sibling attribute. If it does it returns + a pointer to the start of the sibling die in the + .debug_info section. Otherwise it behaves the + same as the want_AT_sibling false case. + + If the want_AT_sibling flag is false, it returns + a pointer to the immediately adjacent die in the + .debug_info section. + + Die_info_end points to the end of the .debug_info + portion for the cu the die belongs to. It is used + to check that the search for the next die does not + cross the end of the current cu. Cu_info_start points + to the start of the .debug_info portion for the + current cu, and is used to add to the offset for + DW_AT_sibling attributes. Finally, has_die_child + is a pointer to a Dwarf_Bool that is set true if + the present die has children, false otherwise. + However, in case want_AT_child is true and the die + has a DW_AT_sibling attribute *has_die_child is set + false to indicate that the children are being skipped. + + die_info_end points to the last byte+1 of the cu. + +*/ +static Dwarf_Byte_Ptr +_dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr, + Dwarf_CU_Context cu_context, + Dwarf_Byte_Ptr die_info_end, + Dwarf_Byte_Ptr cu_info_start, + Dwarf_Bool want_AT_sibling, + Dwarf_Bool * has_die_child) +{ + Dwarf_Byte_Ptr info_ptr; + Dwarf_Byte_Ptr abbrev_ptr; + Dwarf_Word abbrev_code; + Dwarf_Abbrev_List abbrev_list; + Dwarf_Half attr; + Dwarf_Half attr_form; + Dwarf_Unsigned offset; + Dwarf_Word leb128_length; + Dwarf_Unsigned utmp; + Dwarf_Debug dbg; + + info_ptr = die_info_ptr; + DECODE_LEB128_UWORD(info_ptr, utmp); + abbrev_code = (Dwarf_Word) utmp; + if (abbrev_code == 0) { + return NULL; + } + + abbrev_list = _dwarf_get_abbrev_for_code(cu_context, abbrev_code); + if (abbrev_list == NULL) { + return (NULL); + } + dbg = cu_context->cc_dbg; + + *has_die_child = abbrev_list->ab_has_child; + + abbrev_ptr = abbrev_list->ab_abbrev_ptr; + do { + Dwarf_Unsigned utmp2; + + DECODE_LEB128_UWORD(abbrev_ptr, utmp2); + attr = (Dwarf_Half) utmp2; + DECODE_LEB128_UWORD(abbrev_ptr, utmp2); + attr_form = (Dwarf_Half) utmp2; + if (attr_form == DW_FORM_indirect) { + Dwarf_Unsigned utmp6; + + /* READ_UNALIGNED does update info_ptr */ + DECODE_LEB128_UWORD(info_ptr, utmp6); + attr_form = (Dwarf_Half) utmp6; + + } + + if (want_AT_sibling && attr == DW_AT_sibling) { + switch (attr_form) { + case DW_FORM_ref1: + offset = *(Dwarf_Small *) info_ptr; + break; + case DW_FORM_ref2: + READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, + info_ptr, sizeof(Dwarf_Half)); + break; + case DW_FORM_ref4: + READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, + info_ptr, sizeof(Dwarf_ufixed)); + break; + case DW_FORM_ref8: + READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, + info_ptr, sizeof(Dwarf_Unsigned)); + break; + case DW_FORM_ref_udata: + offset = + _dwarf_decode_u_leb128(info_ptr, &leb128_length); + break; + default: + return (NULL); + } + + /* Reset *has_die_child to indicate children skipped. */ + *has_die_child = false; + + /* A value beyond die_info_end indicates an error. Exactly + at die_info_end means 1-past-cu-end and simply means we + are at the end, do not return NULL. Higher level code + will detect that we are at the end. */ + if (cu_info_start + offset > die_info_end) { + /* Error case, bad DWARF. */ + return (NULL); + } + /* At or before end-of-cu */ + return (cu_info_start + offset); + } + + if (attr_form != 0) { + info_ptr += _dwarf_get_size_of_val(cu_context->cc_dbg, + attr_form, info_ptr, + cu_context-> + cc_length_size); + /* It is ok for info_ptr == die_info_end, as we will test + later before using a too-large info_ptr */ + if (info_ptr > die_info_end) { + /* More than one-past-end indicates a bug somewhere, + likely bad dwarf generation. */ + return (NULL); + } + } + } while (attr != 0 || attr_form != 0); + + return (info_ptr); +} + + +/* + Given a Dwarf_Debug dbg, and a Dwarf_Die die, it returns + a Dwarf_Die for the sibling of die. In case die is NULL, + it returns (thru ptr) a Dwarf_Die for the first die in the current + cu in dbg. Returns DW_DLV_ERROR on error. + + It is assumed that every sibling chain including those with + only one element is terminated with a NULL die, except a + chain with only a NULL die. + + The algorithm moves from one die to the adjacent one. It + returns when the depth of children it sees equals the number + of sibling chain terminations. A single count, child_depth + is used to track the depth of children and sibling terminations + encountered. Child_depth is incremented when a die has the + Has-Child flag set unless the child happens to be a NULL die. + Child_depth is decremented when a die has Has-Child false, + and the adjacent die is NULL. Algorithm returns when + child_depth is 0. + + **NOTE: Do not modify input die, since it is used at the end. +*/ +int +dwarf_siblingof(Dwarf_Debug dbg, + Dwarf_Die die, + Dwarf_Die * caller_ret_die, Dwarf_Error * error) +{ + Dwarf_Die ret_die; + Dwarf_Byte_Ptr die_info_ptr; + Dwarf_Byte_Ptr cu_info_start = 0; + + /* die_info_end points 1-past end of die (once set) */ + Dwarf_Byte_Ptr die_info_end = 0; + Dwarf_Half abbrev_code; + Dwarf_Unsigned utmp; + + + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + + if (die == NULL) { + /* Find root die of cu */ + /* die_info_end is untouched here, need not be set in this + branch. */ + Dwarf_Off off2; + + /* If we've not loaded debug_info, de_cu_context will be NULL, + so no need to laod */ + + if (dbg->de_cu_context == NULL) { + _dwarf_error(dbg, error, DW_DLE_DBG_NO_CU_CONTEXT); + return (DW_DLV_ERROR); + } + + off2 = dbg->de_cu_context->cc_debug_info_offset; + die_info_ptr = dbg->de_debug_info + + off2 + _dwarf_length_of_cu_header(dbg, off2); + } else { + /* Find sibling die. */ + Dwarf_Bool has_child = false; + Dwarf_Sword child_depth; + + /* We cannot have a legal die unless debug_info was loaded, so + no need to load debug_info here. */ + CHECK_DIE(die, DW_DLV_ERROR); + + die_info_ptr = die->di_debug_info_ptr; + if (*die_info_ptr == 0) { + return (DW_DLV_NO_ENTRY); + } + cu_info_start = dbg->de_debug_info + + die->di_cu_context->cc_debug_info_offset; + die_info_end = cu_info_start + die->di_cu_context->cc_length + + die->di_cu_context->cc_length_size + + die->di_cu_context->cc_extension_size; + + if ((*die_info_ptr) == 0) { + return (DW_DLV_NO_ENTRY); + } + child_depth = 0; + do { + die_info_ptr = _dwarf_next_die_info_ptr(die_info_ptr, + die->di_cu_context, + die_info_end, + cu_info_start, true, + &has_child); + if (die_info_ptr == NULL) { + _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL); + return (DW_DLV_ERROR); + } + + /* die_info_end is one past end. Do not read it! + A test for ``!= die_info_end'' would work as well, + but perhaps < reads more like the meaning. */ + if(die_info_ptr < die_info_end) { + if ((*die_info_ptr) == 0 && has_child) { + die_info_ptr++; + has_child = false; + } + } + + /* die_info_ptr can be one-past-end. */ + if ((die_info_ptr == die_info_end) || + ((*die_info_ptr) == 0)) { + for (; child_depth > 0 && *die_info_ptr == 0; + child_depth--, die_info_ptr++); + } else { + child_depth = has_child ? child_depth + 1 : child_depth; + } + + } while (child_depth != 0); + } + + /* die_info_ptr > die_info_end is really a bug (possibly in dwarf + generation)(but we are past end, no more DIEs here), whereas + die_info_ptr == die_info_end means 'one past end, no more DIEs + here'. */ + if (die != NULL && die_info_ptr >= die_info_end) { + return (DW_DLV_NO_ENTRY); + } + + if ((*die_info_ptr) == 0) { + return (DW_DLV_NO_ENTRY); + } + + ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1); + if (ret_die == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + ret_die->di_debug_info_ptr = die_info_ptr; + ret_die->di_cu_context = + die == NULL ? dbg->de_cu_context : die->di_cu_context; + + DECODE_LEB128_UWORD(die_info_ptr, utmp); + abbrev_code = (Dwarf_Half) utmp; + if (abbrev_code == 0) { + /* Zero means a null DIE */ + dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); + return (DW_DLV_NO_ENTRY); + } + ret_die->di_abbrev_list = + _dwarf_get_abbrev_for_code(ret_die->di_cu_context, abbrev_code); + if (ret_die->di_abbrev_list == NULL || (die == NULL && + ret_die->di_abbrev_list-> + ab_tag != + DW_TAG_compile_unit)) { + dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); + _dwarf_error(dbg, error, DW_DLE_FIRST_DIE_NOT_CU); + return (DW_DLV_ERROR); + } + + *caller_ret_die = ret_die; + return (DW_DLV_OK); +} + + +int +dwarf_child(Dwarf_Die die, + Dwarf_Die * caller_ret_die, Dwarf_Error * error) +{ + Dwarf_Byte_Ptr die_info_ptr = 0; + + /* die_info_end points one-past-end of die area. */ + Dwarf_Byte_Ptr die_info_end = 0; + Dwarf_Die ret_die = 0; + Dwarf_Bool has_die_child = 0; + Dwarf_Debug dbg; + Dwarf_Half abbrev_code = 0; + Dwarf_Unsigned utmp = 0; + + + CHECK_DIE(die, DW_DLV_ERROR); + dbg = die->di_cu_context->cc_dbg; + die_info_ptr = die->di_debug_info_ptr; + + /* NULL die has no child. */ + if ((*die_info_ptr) == 0) + return (DW_DLV_NO_ENTRY); + + die_info_end = dbg->de_debug_info + + die->di_cu_context->cc_debug_info_offset + + die->di_cu_context->cc_length + + die->di_cu_context->cc_length_size + + die->di_cu_context->cc_extension_size; + + die_info_ptr = + _dwarf_next_die_info_ptr(die_info_ptr, die->di_cu_context, + die_info_end, NULL, false, + &has_die_child); + if (die_info_ptr == NULL) { + _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL); + return (DW_DLV_ERROR); + } + + if (!has_die_child) + return (DW_DLV_NO_ENTRY); + + ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1); + if (ret_die == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + ret_die->di_debug_info_ptr = die_info_ptr; + ret_die->di_cu_context = die->di_cu_context; + + DECODE_LEB128_UWORD(die_info_ptr, utmp); + abbrev_code = (Dwarf_Half) utmp; + if (abbrev_code == 0) { + /* We have arrived at a null DIE, at the end of a CU or the end + of a list of siblings. */ + *caller_ret_die = 0; + dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); + return DW_DLV_NO_ENTRY; + } + ret_die->di_abbrev_list = + _dwarf_get_abbrev_for_code(die->di_cu_context, abbrev_code); + if (ret_die->di_abbrev_list == NULL) { + dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); + _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + return (DW_DLV_ERROR); + } + + *caller_ret_die = ret_die; + return (DW_DLV_OK); +} + +/* + Given a die offset, this returns + a pointer to a DIE thru *new_die. + It is up to the caller to do a + dwarf_dealloc(dbg,*new_die,DW_DLE_DIE); +*/ +int +dwarf_offdie(Dwarf_Debug dbg, + Dwarf_Off offset, Dwarf_Die * new_die, Dwarf_Error * error) +{ + Dwarf_CU_Context cu_context; + Dwarf_Off new_cu_offset = 0; + Dwarf_Die die = 0; + Dwarf_Byte_Ptr info_ptr = 0; + Dwarf_Half abbrev_code = 0; + Dwarf_Unsigned utmp = 0; + + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + + cu_context = _dwarf_find_CU_Context(dbg, offset); + if (cu_context == NULL) + cu_context = _dwarf_find_offdie_CU_Context(dbg, offset); + + if (cu_context == NULL) { + int res = _dwarf_load_debug_info(dbg, error); + + if (res != DW_DLV_OK) { + return res; + } + + if (dbg->de_offdie_cu_context_end != NULL) { + Dwarf_CU_Context lcu_context = + dbg->de_offdie_cu_context_end; + new_cu_offset = + lcu_context->cc_debug_info_offset + + lcu_context->cc_length + + lcu_context->cc_length_size + + lcu_context->cc_extension_size; + } + + + do { + if ((new_cu_offset + + _dwarf_length_of_cu_header_simple(dbg)) >= + dbg->de_debug_info_size) { + _dwarf_error(dbg, error, DW_DLE_OFFSET_BAD); + return (DW_DLV_ERROR); + } + + cu_context = + _dwarf_make_CU_Context(dbg, new_cu_offset, error); + if (cu_context == NULL) { + /* Error if CU Context could not be made. Since + _dwarf_make_CU_Context has already registered an + error we do not do that here: we let the lower error + pass thru. */ + + return (DW_DLV_ERROR); + } + + if (dbg->de_offdie_cu_context == NULL) { + dbg->de_offdie_cu_context = cu_context; + dbg->de_offdie_cu_context_end = cu_context; + } else { + dbg->de_offdie_cu_context_end->cc_next = cu_context; + dbg->de_offdie_cu_context_end = cu_context; + } + + new_cu_offset = new_cu_offset + cu_context->cc_length + + cu_context->cc_length_size; + + } while (offset >= new_cu_offset); + } + + die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1); + if (die == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + die->di_cu_context = cu_context; + + info_ptr = dbg->de_debug_info + offset; + die->di_debug_info_ptr = info_ptr; + DECODE_LEB128_UWORD(info_ptr, utmp); + abbrev_code = (Dwarf_Half) utmp; + if (abbrev_code == 0) { + /* we are at a null DIE (or there is a bug). */ + *new_die = 0; + dwarf_dealloc(dbg, die, DW_DLA_DIE); + return DW_DLV_NO_ENTRY; + } + + die->di_abbrev_list = + _dwarf_get_abbrev_for_code(cu_context, abbrev_code); + if (die->di_abbrev_list == NULL) { + dwarf_dealloc(dbg, die, DW_DLA_DIE); + _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL); + return (DW_DLV_ERROR); + } + + *new_die = die; + return (DW_DLV_OK); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_die_deliv.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_die_deliv.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,56 @@ +/* + + Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + + +/* + This struct holds information about a abbreviation. + It is put in the hash table for abbreviations for + a compile-unit. +*/ +struct Dwarf_Abbrev_List_s { + + Dwarf_Word ab_code; + Dwarf_Half ab_tag; + Dwarf_Half ab_has_child; + + /* + Points to start of attribute and form pairs in the .debug_abbrev + section for the abbrev. */ + Dwarf_Byte_Ptr ab_abbrev_ptr; + + struct Dwarf_Abbrev_List_s *ab_next; +}; diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_error.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_error.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,388 @@ +/* + + Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#ifdef HAVE_ELF_H +#include +#endif + +#include +#include +#include +#include + +/* Array to hold string representation of errors. Any time a + define is added to the list in libdwarf.h, a string should be + added to this Array +*/ + +const char *_dwarf_errmsgs[] = { + + "No error (0)\n", + "DW_DLE_VMM 1 dwarf format/library version mismatch", + "DW_DLE_MAP 2 memory map failure", + "DW_DLE_LEE 3 libelf error", + "DW_DLE_NDS 4 no debug section", + "DW_DLE_NLS 5 no line section ", + "DW_DLE_ID 6 invalid descriptor for query ", + "DW_DLE_IOF 7 I/O failure ", + "DW_DLE_MAF 8 memory allocation failure ", + "DW_DLE_IA 9 invalid argument ", + "DW_DLE_MDE 10 mangled debugging entry ", + "DW_DLE_MLE 11 mangled line number entry ", + "DW_DLE_FNO 12 file not open ", + "DW_DLE_FNR 13 file not a regular file ", + "DW_DLE_FWA 14 file open with wrong access ", + "DW_DLE_NOB 15 not an object file ", + "DW_DLE_MOF 16 mangled object file header ", + "DW_DLE_EOLL 17 end of location list entries ", + "DW_DLE_NOLL 18 no location list section ", + "DW_DLE_BADOFF 19 Invalid offset ", + "DW_DLE_EOS 20 end of section ", + "DW_DLE_ATRUNC 21 abbreviations section appears truncated", + "DW_DLE_BADBITC 22 Address size passed to dwarf bad", + + "DW_DLE_DBG_ALLOC 23 Unable to malloc a Dwarf_Debug structure", + "DW_DLE_FSTAT_ERROR 24 The file fd passed to dwarf_init " + "cannot be fstat()ed", + "DW_DLE_FSTAT_MODE_ERROR 25 The file mode bits do not " + "indicate that the file being opened via " + "dwarf_init() is a normal file", + "DW_DLE_INIT_ACCESS_WRONG 26 A call to dwarf_init had an " + "access of other than DW_DLC_READ", + "DW_DLE_ELF_BEGIN_ERROR 27 a call to " + "elf_begin(... ELF_C_READ_MMAP... ) failed", + "DW_DLE_ELF_GETEHDR_ERROR 28 a call to " + "elf32_getehdr() or elf64_getehdr() failed", + "DW_DLE_ELF_GETSHDR_ERROR 29 a call to " + "elf32_getshdr() or elf64_getshdr() failed", + "DW_DLE_ELF_STRPTR_ERROR 30 a call to " + "elf_strptr() failed trying to get a section name", + "DW_DLE_DEBUG_INFO_DUPLICATE 31 Only one .debug_info " + "section is allowed", + "DW_DLE_DEBUG_INFO_NULL 32 .debug_info section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_ABBREV_DUPLICATE 33 Only one .debug_abbrev " + "section is allowed", + "DW_DLE_DEBUG_ABBREV_NULL 34 .debug_abbrev section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_ARANGES_DUPLICATE 35 Only one .debug_aranges " + "section is allowed", + "DW_DLE_DEBUG_ARANGES_NULL 36 .debug_aranges section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_LINE_DUPLICATE 37 Only one .debug_line " + "section is allowed", + "DW_DLE_DEBUG_LINE_NULL (38) .debug_line section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_LOC_DUPLICATE (39) Only one .debug_loc " + "section is allowed", + "DW_DLE_DEBUG_LOC_NULL (40) .debug_loc section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_MACINFO_DUPLICATE (41) Only one .debug_macinfo " + "section is allowed", + "DW_DLE_DEBUG_MACINFO_NULL (42) .debug_macinfo section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_PUBNAMES_DUPLICATE (43) Only one .debug_pubnames " + "section is allowed", + "DW_DLE_DEBUG_PUBNAMES_NULL (44) .debug_pubnames section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_STR_DUPLICATE (45) Only one .debug_str " + "section is allowed", + "DW_DLE_DEBUG_STR_NULL (46) .debug_str section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_CU_LENGTH_ERROR (47)", + "DW_DLE_VERSION_STAMP_ERROR (48)", + "DW_DLE_ABBREV_OFFSET_ERROR (49)", + "DW_DLE_ADDRESS_SIZE_ERROR (50)", + "DW_DLE_DEBUG_INFO_PTR_NULL (51)", + "DW_DLE_DIE_NULL (52)", + "DW_DLE_STRING_OFFSET_BAD (53)", + "DW_DLE_DEBUG_LINE_LENGTH_BAD (54)", + "DW_DLE_LINE_PROLOG_LENGTH_BAD (55)", + "DW_DLE_LINE_NUM_OPERANDS_BAD", + "DW_DLE_LINE_SET_ADDR_ERROR", + "DW_DLE_LINE_EXT_OPCODE_BAD", + "DW_DLE_DWARF_LINE_NULL", + "DW_DLE_INCL_DIR_NUM_BAD", + "DW_DLE_LINE_FILE_NUM_BAD", + "DW_DLE_ALLOC_FAIL", + "DW_DLE_NO_CALLBACK_FUNC", + "DW_DLE_SECT_ALLOC", + "DW_DLE_FILE_ENTRY_ALLOC", + "DW_DLE_LINE_ALLOC", + "DW_DLE_FPGM_ALLOC", + "DW_DLE_INCDIR_ALLOC", + "DW_DLE_STRING_ALLOC", + "DW_DLE_CHUNK_ALLOC", + "DW_DLE_BYTEOFF_ERR", + "DW_DLE_CIE_ALLOC", + "DW_DLE_FDE_ALLOC", + "DW_DLE_REGNO_OVFL", + "DW_DLE_CIE_OFFS_ALLOC", + "DW_DLE_WRONG_ADDRESS", + "DW_DLE_EXTRA_NEIGHBORS", + "DW_DLE_WRONG_TAG", + "DW_DLE_DIE_ALLOC", + "DW_DLE_PARENT_EXISTS", + "DW_DLE_DBG_NULL", + "DW_DLE_DEBUGLINE_ERROR", + "DW_DLE_DEBUGFRAME_ERROR", + "DW_DLE_DEBUGINFO_ERROR", + "DW_DLE_ATTR_ALLOC", + "DW_DLE_ABBREV_ALLOC", + "DW_DLE_OFFSET_UFLW", + "DW_DLE_ELF_SECT_ERR", + "DW_DLE_DEBUG_FRAME_LENGTH_BAD", + "DW_DLE_FRAME_VERSION_BAD", + "DW_DLE_CIE_RET_ADDR_REG_ERROR", + "DW_DLE_FDE_NULL", + "DW_DLE_FDE_DBG_NULL", + "DW_DLE_CIE_NULL", + "DW_DLE_CIE_DBG_NULL", + "DW_DLE_FRAME_TABLE_COL_BAD", + "DW_DLE_PC_NOT_IN_FDE_RANGE", + "DW_DLE_CIE_INSTR_EXEC_ERROR", + "DW_DLE_FRAME_INSTR_EXEC_ERROR", + "DW_DLE_FDE_PTR_NULL", + "DW_DLE_RET_OP_LIST_NULL", + "DW_DLE_LINE_CONTEXT_NULL", + "DW_DLE_DBG_NO_CU_CONTEXT", + "DW_DLE_DIE_NO_CU_CONTEXT", + "DW_DLE_FIRST_DIE_NOT_CU", + "DW_DLE_NEXT_DIE_PTR_NULL", + "DW_DLE_DEBUG_FRAME_DUPLICATE Only one .debug_frame " + "section is allowed", + "DW_DLE_DEBUG_FRAME_NULL .debug_frame section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_ABBREV_DECODE_ERROR", + "DW_DLE_DWARF_ABBREV_NULL", + "DW_DLE_ATTR_NULL", + "DW_DLE_DIE_BAD", + "DW_DLE_DIE_ABBREV_BAD", + "DW_DLE_ATTR_FORM_BAD", + "DW_DLE_ATTR_NO_CU_CONTEXT", + "DW_DLE_ATTR_FORM_SIZE_BAD", + "DW_DLE_ATTR_DBG_NULL", + "DW_DLE_BAD_REF_FORM", + "DW_DLE_ATTR_FORM_OFFSET_BAD", + "DW_DLE_LINE_OFFSET_BAD", + "DW_DLE_DEBUG_STR_OFFSET_BAD", + "DW_DLE_STRING_PTR_NULL", + "DW_DLE_PUBNAMES_VERSION_ERROR", + "DW_DLE_PUBNAMES_LENGTH_BAD", + "DW_DLE_GLOBAL_NULL", + "DW_DLE_GLOBAL_CONTEXT_NULL", + "DW_DLE_DIR_INDEX_BAD", + "DW_DLE_LOC_EXPR_BAD", + "DW_DLE_DIE_LOC_EXPR_BAD", + "DW_DLE_ADDR_ALLOC", + "DW_DLE_OFFSET_BAD", + "DW_DLE_MAKE_CU_CONTEXT_FAIL", + "DW_DLE_REL_ALLOC", + "DW_DLE_ARANGE_OFFSET_BAD", + "DW_DLE_SEGMENT_SIZE_BAD", + "DW_DLE_ARANGE_LENGTH_BAD", + "DW_DLE_ARANGE_DECODE_ERROR", + "DW_DLE_ARANGES_NULL", + "DW_DLE_ARANGE_NULL", + "DW_DLE_NO_FILE_NAME", + "DW_DLE_NO_COMP_DIR", + "DW_DLE_CU_ADDRESS_SIZE_BAD", + "DW_DLE_INPUT_ATTR_BAD", + "DW_DLE_EXPR_NULL", + "DW_DLE_BAD_EXPR_OPCODE", + "DW_DLE_EXPR_LENGTH_BAD", + "DW_DLE_MULTIPLE_RELOC_IN_EXPR", + "DW_DLE_ELF_GETIDENT_ERROR", + "DW_DLE_NO_AT_MIPS_FDE", + "DW_DLE_NO_CIE_FOR_FDE", + "DW_DLE_DIE_ABBREV_LIST_NULL", + "DW_DLE_DEBUG_FUNCNAMES_DUPLICATE", + "DW_DLE_DEBUG_FUNCNAMES_NULL .debug_funcnames section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR", + "DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD", + "DW_DLE_FUNC_NULL", + "DW_DLE_FUNC_CONTEXT_NULL", + "DW_DLE_DEBUG_TYPENAMES_DUPLICATE", + "DW_DLE_DEBUG_TYPENAMES_NULL .debug_typenames section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR", + "DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD", + "DW_DLE_TYPE_NULL", + "DW_DLE_TYPE_CONTEXT_NULL", + "DW_DLE_DEBUG_VARNAMES_DUPLICATE", + "DW_DLE_DEBUG_VARNAMES_NULL .debug_varnames section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_VARNAMES_VERSION_ERROR", + "DW_DLE_DEBUG_VARNAMES_LENGTH_BAD", + "DW_DLE_VAR_NULL", + "DW_DLE_VAR_CONTEXT_NULL", + "DW_DLE_DEBUG_WEAKNAMES_DUPLICATE", + "DW_DLE_DEBUG_WEAKNAMES_NULL .debug_weaknames section present but " + "elf_getdata() failed or section is zero-length", + + "DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR", + "DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD", + "DW_DLE_WEAK_NULL", + "DW_DLE_WEAK_CONTEXT_NULL (175)", + "DW_DLE_LOCDESC_COUNT_WRONG (176)", + "DW_DLE_MACINFO_STRING_NULL (177)", + "DW_DLE_MACINFO_STRING_EMPTY (178)", + "DW_DLE_MACINFO_INTERNAL_ERROR_SPACE (179)", + "DW_DLE_MACINFO_MALLOC_FAIL (180)", + "DW_DLE_DEBUGMACINFO_ERROR (181)", + "DW_DLE_DEBUG_MACRO_LENGTH_BAD (182)", + "DW_DLE_DEBUG_MACRO_MAX_BAD (183)", + "DW_DLE_DEBUG_MACRO_INTERNAL_ERR (184)", + "DW_DLE_DEBUG_MACRO_MALLOC_SPACE (185)", + "DW_DLE_DEBUG_MACRO_INCONSISTENT (186)", + "DW_DLE_DF_NO_CIE_AUGMENTATION(187)", + "DW_DLE_DF_REG_NUM_TOO_HIGH(188)", + "DW_DLE_DF_MAKE_INSTR_NO_INIT(189)", + "DW_DLE_DF_NEW_LOC_LESS_OLD_LOC(190)", + "DW_DLE_DF_POP_EMPTY_STACK(191)", + "DW_DLE_DF_ALLOC_FAIL(192)", + "DW_DLE_DF_FRAME_DECODING_ERROR(193)", + "DW_DLE_DEBUG_LOC_SECTION_SHORT(194)", + "DW_DLE_FRAME_AUGMENTATION_UNKNOWN(195)", + "DW_DLA_PUBTYPE_CONTEXT(196)", + "DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD(197)", + "DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR(198)", + "DW_DLE_DEBUG_PUBTYPES_DUPLICATE(199)", + "DW_DLE_FRAME_CIE_DECODE_ERROR(200)", + "DW_DLE_FRAME_REGISTER_UNREPRESENTABLE(201)", + "DW_DLE_FRAME_REGISTER_COUNT_MISMATCH(202)", + "DW_DLE_LINK_LOOP(203)", + + + +}; + + + + +/* + This function performs error handling as described in the + libdwarf consumer document section 3. Dbg is the Dwarf_debug + structure being processed. Error is a pointer to the pointer + to the error descriptor that will be returned. Errval is an + error code listed in dwarf_error.h. +*/ +void +_dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Sword errval) +{ + Dwarf_Error errptr; + + /* + Allow NULL dbg on entry, since sometimes that can happen and we + want to report the upper-level error, not this one. */ + if (error != NULL) { + + /* + If dbg is NULL, use the alternate error struct. However, + this will overwrite the earlier error. */ + if (dbg != NULL) { + errptr = + (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1); + if (errptr == NULL) { + fprintf(stderr, + "Could not allocate Dwarf_Error structure, " + "abort() in libdwarf.\n"); + abort(); + } + } else { + /* We have no dbg to work with. dwarf_init failed. We hack + up a special area. */ + errptr = _dwarf_special_no_dbg_error_malloc(); + if (errptr == NULL) { + fprintf(stderr, + "Could not allocate Dwarf_Error structure, " + "abort() in libdwarf..\n"); + abort(); + } + } + + errptr->er_errval = errval; + *error = errptr; + return; + } + + if (dbg != NULL && dbg->de_errhand != NULL) { + errptr = (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1); + if (errptr == NULL) { + fprintf(stderr, "Could not allocate Dwarf_Error structure," + " abort() in libdwarf.\n"); + abort(); + } + errptr->er_errval = errval; + dbg->de_errhand(errptr, dbg->de_errarg); + return; + } + fprintf(stderr, + "abort() in libdwarf. No error argument, no handler.\n"); + abort(); +} + + +Dwarf_Unsigned +dwarf_errno(Dwarf_Error error) +{ + if (error == NULL) { + return (0); + } + + return (error->er_errval); +} + + +/* +*/ +char * +dwarf_errmsg(Dwarf_Error error) +{ + if (error == NULL) { + return "Dwarf_Error is NULL"; + } + + if (error->er_errval > (sizeof(_dwarf_errmsgs) / sizeof(char *))) { + return "Dwarf_Error value out of range"; + } + + return ((char *) _dwarf_errmsgs[error->er_errval]); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_error.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_error.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,43 @@ +/* + + Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +void _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, + Dwarf_Sword errval); + +struct Dwarf_Error_s { + Dwarf_Sword er_errval; +}; diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_form.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_form.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,810 @@ +/* + + Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include "dwarf_die_deliv.h" + +int +dwarf_hasform(Dwarf_Attribute attr, + Dwarf_Half form, + Dwarf_Bool * return_bool, Dwarf_Error * error) +{ + Dwarf_CU_Context cu_context; + + if (attr == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); + return (DW_DLV_ERROR); + } + + cu_context = attr->ar_cu_context; + if (cu_context == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); + return (DW_DLV_ERROR); + } + + if (cu_context->cc_dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); + return (DW_DLV_ERROR); + } + + *return_bool = (attr->ar_attribute_form == form); + return DW_DLV_OK; +} + +/* Not often called, we do not worry about efficiency here. + The dwarf_whatform() call does the sanity checks for us. +*/ +int +dwarf_whatform_direct(Dwarf_Attribute attr, + Dwarf_Half * return_form, Dwarf_Error * error) +{ + int res = dwarf_whatform(attr, return_form, error); + + if (res != DW_DLV_OK) { + return res; + } + + *return_form = attr->ar_attribute_form_direct; + return (DW_DLV_OK); +} +void * +dwarf_uncompress_integer_block( + Dwarf_Debug dbg, + Dwarf_Bool unit_is_signed, + Dwarf_Small unit_length_in_bits, + void* input_block, + Dwarf_Unsigned input_length_in_bytes, + Dwarf_Unsigned* output_length_in_units_ptr, + Dwarf_Error* error +) +{ + Dwarf_Unsigned output_length_in_units; + void * output_block; + int i; + char * ptr; + int remain; + Dwarf_sfixed * array; + + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return((void *)DW_DLV_BADADDR); + } + + if (unit_is_signed == false || + unit_length_in_bits != 32 || + input_block == NULL || + input_length_in_bytes == 0 || + output_length_in_units_ptr == NULL) { + + _dwarf_error(NULL, error, DW_DLE_BADBITC); + return ((void *) DW_DLV_BADADDR); + } + + /* At this point we assume the format is: signed 32 bit */ + + /* first uncompress everything to find the total size. */ + + output_length_in_units = 0; + remain = input_length_in_bytes; + ptr = input_block; + while (remain > 0) { + Dwarf_Signed num; + Dwarf_Word len; + num = _dwarf_decode_s_leb128((unsigned char *)ptr, &len); + ptr += len; + remain -= len; + output_length_in_units++; + } + + if (remain != 0) { + _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL); + return((void *)DW_DLV_BADADDR); + } + + /* then alloc */ + + output_block = (void *) + _dwarf_get_alloc(dbg, + DW_DLA_STRING, + output_length_in_units * (unit_length_in_bits / 8)); + if (output_block == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return((void*)DW_DLV_BADADDR); + } + + /* then uncompress again and copy into new buffer */ + + array = (Dwarf_sfixed *) output_block; + remain = input_length_in_bytes; + ptr = input_block; + for (i=0; i0; i++) { + Dwarf_Signed num; + Dwarf_Word len; + num = _dwarf_decode_s_leb128((unsigned char *)ptr, &len); + ptr += len; + remain -= len; + array[i] = num; + } + + if (remain != 0) { + dwarf_dealloc(dbg, (unsigned char *)output_block, DW_DLA_STRING); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return((Dwarf_P_Attribute)DW_DLV_BADADDR); + } + + *output_length_in_units_ptr = output_length_in_units; + return output_block; +} + +void +dwarf_dealloc_uncompressed_block(Dwarf_Debug dbg, void * space) +{ + dwarf_dealloc(dbg, space, DW_DLA_STRING); +} + + +int +dwarf_whatform(Dwarf_Attribute attr, + Dwarf_Half * return_form, Dwarf_Error * error) +{ + Dwarf_CU_Context cu_context; + + if (attr == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); + return (DW_DLV_ERROR); + } + + cu_context = attr->ar_cu_context; + if (cu_context == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); + return (DW_DLV_ERROR); + } + + if (cu_context->cc_dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); + return (DW_DLV_ERROR); + } + + *return_form = attr->ar_attribute_form; + return (DW_DLV_OK); +} + + +/* + This function is analogous to dwarf_whatform. + It returns the attribute in attr instead of + the form. +*/ +int +dwarf_whatattr(Dwarf_Attribute attr, + Dwarf_Half * return_attr, Dwarf_Error * error) +{ + Dwarf_CU_Context cu_context; + + if (attr == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); + return (DW_DLV_ERROR); + } + + cu_context = attr->ar_cu_context; + if (cu_context == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); + return (DW_DLV_ERROR); + } + + if (cu_context->cc_dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); + return (DW_DLV_ERROR); + } + + *return_attr = (attr->ar_attribute); + return DW_DLV_OK; +} + + +/* + DW_FORM_ref_addr is considered an incorrect form + for this call because this function returns an + offset within the local CU thru the pointer. + + DW_FORM_ref_addr is a global-offset into the debug_info section. + A DW_FORM_ref_addr cannot be returned by this interface: + see dwarf_global_formref(); + + DW_FORM_ref_addr has a value which was documented in + DWARF2 as address-size but which was always an offset + so should have always been offset size (wording + corrected in DWARF3). + +*/ +int +dwarf_formref(Dwarf_Attribute attr, + Dwarf_Off * ret_offset, Dwarf_Error * error) +{ + Dwarf_Debug dbg; + Dwarf_Unsigned offset; + Dwarf_CU_Context cu_context; + + + if (attr == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); + return (DW_DLV_ERROR); + } + + cu_context = attr->ar_cu_context; + if (cu_context == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); + return (DW_DLV_ERROR); + } + + if (cu_context->cc_dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); + return (DW_DLV_ERROR); + } + dbg = cu_context->cc_dbg; + + switch (attr->ar_attribute_form) { + + case DW_FORM_ref1: + offset = *(Dwarf_Small *) attr->ar_debug_info_ptr; + break; + + case DW_FORM_ref2: + READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, + attr->ar_debug_info_ptr, sizeof(Dwarf_Half)); + break; + + case DW_FORM_ref4: + READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, + attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed)); + break; + + case DW_FORM_ref8: + READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, + attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned)); + break; + + case DW_FORM_ref_udata: + offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL); + break; + + default: + _dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM); + return (DW_DLV_ERROR); + } + + /* Check that offset is within current cu portion of .debug_info. */ + + if (offset >= cu_context->cc_length + + cu_context->cc_length_size + cu_context->cc_extension_size) { + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD); + return (DW_DLV_ERROR); + } + + *ret_offset = (offset); + return DW_DLV_OK; +} + +/* + Since this returns section-relative debug_info offsets, + this can represent all REFERENCE forms correctly + and allows all forms. + + DW_FORM_ref_addr has a value which was documented in + DWARF2 as address-size but which was always an offset + so should have always been offset size (wording + corrected in DWARF3). + +*/ +int +dwarf_global_formref(Dwarf_Attribute attr, + Dwarf_Off * ret_offset, Dwarf_Error * error) +{ + Dwarf_Debug dbg; + Dwarf_Unsigned offset; + Dwarf_Addr ref_addr; + Dwarf_CU_Context cu_context; + + if (attr == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); + return (DW_DLV_ERROR); + } + + cu_context = attr->ar_cu_context; + if (cu_context == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); + return (DW_DLV_ERROR); + } + + if (cu_context->cc_dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); + return (DW_DLV_ERROR); + } + dbg = cu_context->cc_dbg; + + switch (attr->ar_attribute_form) { + + case DW_FORM_ref1: + offset = *(Dwarf_Small *) attr->ar_debug_info_ptr; + goto fixoffset; + + case DW_FORM_ref2: + READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, + attr->ar_debug_info_ptr, sizeof(Dwarf_Half)); + goto fixoffset; + + case DW_FORM_ref4: + READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, + attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed)); + goto fixoffset; + + case DW_FORM_ref8: + READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, + attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned)); + goto fixoffset; + + case DW_FORM_ref_udata: + offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL); + + fixoffset: /* we have a local offset, make it + global */ + + /* check legality of offset */ + if (offset >= cu_context->cc_length + + cu_context->cc_length_size + + cu_context->cc_extension_size) { + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD); + return (DW_DLV_ERROR); + } + + /* globalize the offset */ + offset += cu_context->cc_debug_info_offset; + break; + + case DW_FORM_ref_addr: + /* This offset is defined to be debug_info global already, so + use this value unaltered. */ + READ_UNALIGNED(dbg, ref_addr, Dwarf_Addr, + attr->ar_debug_info_ptr, + cu_context->cc_length_size); + offset = ref_addr; + break; + default: + _dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM); + return (DW_DLV_ERROR); + } + + /* Check that offset is within current cu portion of .debug_info. */ + + *ret_offset = (offset); + return DW_DLV_OK; +} + + +int +dwarf_formaddr(Dwarf_Attribute attr, + Dwarf_Addr * return_addr, Dwarf_Error * error) +{ + Dwarf_Debug dbg; + Dwarf_Addr ret_addr; + Dwarf_CU_Context cu_context; + + if (attr == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); + return (DW_DLV_ERROR); + } + + cu_context = attr->ar_cu_context; + if (cu_context == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); + return (DW_DLV_ERROR); + } + + if (cu_context->cc_dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); + return (DW_DLV_ERROR); + } + dbg = cu_context->cc_dbg; + + if (attr->ar_attribute_form == DW_FORM_addr + /* || attr->ar_attribute_form == DW_FORM_ref_addr Allowance of + DW_FORM_ref_addr was a mistake. The value returned in that + case is NOT an address it is a global debug_info offset (ie, + not CU-relative offset within the CU in debug_info). The + Dwarf document refers to it as an address (misleadingly) in + sec 6.5.4 where it describes the reference form. It is + address-sized so that the linker can easily update it, but + it is a reference inside the debug_info section. No longer + allowed. */ + ) { + + READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr, + attr->ar_debug_info_ptr, dbg->de_pointer_size); + *return_addr = ret_addr; + return (DW_DLV_OK); + } + + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); +} + + +int +dwarf_formflag(Dwarf_Attribute attr, + Dwarf_Bool * ret_bool, Dwarf_Error * error) +{ + Dwarf_CU_Context cu_context; + + if (attr == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); + return (DW_DLV_ERROR); + } + + cu_context = attr->ar_cu_context; + if (cu_context == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); + return (DW_DLV_ERROR); + } + + if (cu_context->cc_dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); + return (DW_DLV_ERROR); + } + + if (attr->ar_attribute_form == DW_FORM_flag) { + *ret_bool = (*(Dwarf_Small *) attr->ar_debug_info_ptr != 0); + return (DW_DLV_OK); + } + _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); +} + + +int +dwarf_formudata(Dwarf_Attribute attr, + Dwarf_Unsigned * return_uval, Dwarf_Error * error) +{ + Dwarf_Unsigned ret_value; + Dwarf_Debug dbg; + Dwarf_CU_Context cu_context; + + if (attr == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); + return (DW_DLV_ERROR); + } + + + cu_context = attr->ar_cu_context; + if (cu_context == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); + return (DW_DLV_ERROR); + } + + dbg = cu_context->cc_dbg; + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); + return (DW_DLV_ERROR); + } + + switch (attr->ar_attribute_form) { + + case DW_FORM_data1: + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + attr->ar_debug_info_ptr, sizeof(Dwarf_Small)); + *return_uval = ret_value; + return DW_DLV_OK; + + /* READ_UNALIGNED does the right thing as it reads + the right number bits and generates host order. + So we can just assign to *return_uval. */ + case DW_FORM_data2:{ + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + attr->ar_debug_info_ptr, sizeof(Dwarf_Half)); + *return_uval = ret_value; + return DW_DLV_OK; + } + + case DW_FORM_data4:{ + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + attr->ar_debug_info_ptr, + sizeof(Dwarf_ufixed)); + *return_uval = ret_value; + return DW_DLV_OK; + } + + case DW_FORM_data8:{ + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + attr->ar_debug_info_ptr, + sizeof(Dwarf_Unsigned)); + *return_uval = ret_value; + return DW_DLV_OK; + } + + case DW_FORM_udata: + ret_value = + (_dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL)); + *return_uval = ret_value; + return DW_DLV_OK; + + + /* see bug 583450. We do not allow reading sdata from a udata + value. Caller can retry, calling sdata */ + + + default: + break; + } + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); +} + + +int +dwarf_formsdata(Dwarf_Attribute attr, + Dwarf_Signed * return_sval, Dwarf_Error * error) +{ + Dwarf_Signed ret_value; + Dwarf_Debug dbg; + Dwarf_CU_Context cu_context; + + if (attr == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); + return (DW_DLV_ERROR); + } + + cu_context = attr->ar_cu_context; + if (cu_context == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); + return (DW_DLV_ERROR); + } + + dbg = cu_context->cc_dbg; + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); + return (DW_DLV_ERROR); + } + + switch (attr->ar_attribute_form) { + + case DW_FORM_data1: + *return_sval = (*(Dwarf_Sbyte *) attr->ar_debug_info_ptr); + return DW_DLV_OK; + + /* READ_UNALIGNED does not sign extend. + So we have to use a cast to get the + value sign extended in the right way for each case. */ + case DW_FORM_data2:{ + READ_UNALIGNED(dbg, ret_value, Dwarf_Signed, + attr->ar_debug_info_ptr, + sizeof(Dwarf_Shalf)); + *return_sval = (Dwarf_Shalf) ret_value; + return DW_DLV_OK; + + } + + case DW_FORM_data4:{ + READ_UNALIGNED(dbg, ret_value, Dwarf_Signed, + attr->ar_debug_info_ptr, + sizeof(Dwarf_sfixed)); + *return_sval = (Dwarf_sfixed) ret_value; + return DW_DLV_OK; + } + + case DW_FORM_data8:{ + READ_UNALIGNED(dbg, ret_value, Dwarf_Signed, + attr->ar_debug_info_ptr, + sizeof(Dwarf_Signed)); + *return_sval = (Dwarf_Signed) ret_value; + return DW_DLV_OK; + } + + case DW_FORM_sdata: + ret_value = + (_dwarf_decode_s_leb128(attr->ar_debug_info_ptr, NULL)); + *return_sval = ret_value; + return DW_DLV_OK; + + + /* see bug 583450. We do not allow reading sdata from a udata + value. Caller can retry, calling sdata */ + + + default: + break; + } + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); +} + + +int +dwarf_formblock(Dwarf_Attribute attr, + Dwarf_Block ** return_block, Dwarf_Error * error) +{ + Dwarf_CU_Context cu_context; + Dwarf_Debug dbg; + Dwarf_Unsigned length; + Dwarf_Small *data; + Dwarf_Word leb128_length; + Dwarf_Block *ret_block; + + if (attr == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); + return (DW_DLV_ERROR); + } + + cu_context = attr->ar_cu_context; + if (cu_context == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); + return (DW_DLV_ERROR); + } + + if (cu_context->cc_dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); + return (DW_DLV_ERROR); + } + dbg = cu_context->cc_dbg; + + switch (attr->ar_attribute_form) { + + case DW_FORM_block1: + length = *(Dwarf_Small *) attr->ar_debug_info_ptr; + data = attr->ar_debug_info_ptr + sizeof(Dwarf_Small); + break; + + case DW_FORM_block2: + READ_UNALIGNED(dbg, length, Dwarf_Unsigned, + attr->ar_debug_info_ptr, sizeof(Dwarf_Half)); + data = attr->ar_debug_info_ptr + sizeof(Dwarf_Half); + break; + + case DW_FORM_block4: + READ_UNALIGNED(dbg, length, Dwarf_Unsigned, + attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed)); + data = attr->ar_debug_info_ptr + sizeof(Dwarf_ufixed); + break; + + case DW_FORM_block: + length = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, + &leb128_length); + data = attr->ar_debug_info_ptr + leb128_length; + break; + + default: + _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + + /* Check that block lies within current cu in .debug_info. */ + if (attr->ar_debug_info_ptr + length >= + dbg->de_debug_info + cu_context->cc_debug_info_offset + + cu_context->cc_length + cu_context->cc_length_size + + cu_context->cc_extension_size) { + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD); + return (DW_DLV_ERROR); + } + + ret_block = (Dwarf_Block *) _dwarf_get_alloc(dbg, DW_DLA_BLOCK, 1); + if (ret_block == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + ret_block->bl_len = length; + ret_block->bl_data = (Dwarf_Ptr) data; + ret_block->bl_from_loclist = 0; + ret_block->bl_section_offset = data - dbg->de_debug_info; + + + *return_block = ret_block; + return (DW_DLV_OK); +} + + +/* Contrary to long standing documentation, + The string pointer returned thru return_str must + never have dwarf_dealloc() applied to it. + Documentation fixed July 2005. +*/ +int +dwarf_formstring(Dwarf_Attribute attr, + char **return_str, Dwarf_Error * error) +{ + Dwarf_CU_Context cu_context; + Dwarf_Debug dbg; + Dwarf_Unsigned offset; + int res; + + if (attr == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); + return (DW_DLV_ERROR); + } + + cu_context = attr->ar_cu_context; + if (cu_context == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); + return (DW_DLV_ERROR); + } + + if (cu_context->cc_dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); + return (DW_DLV_ERROR); + } + dbg = cu_context->cc_dbg; + + if (attr->ar_attribute_form == DW_FORM_string) { + + void *begin = attr->ar_debug_info_ptr; + + if (0 == dbg->de_assume_string_in_bounds) { + /* Check that string lies within current cu in .debug_info. + */ + void *end = dbg->de_debug_info + + cu_context->cc_debug_info_offset + + cu_context->cc_length + cu_context->cc_length_size + + cu_context->cc_extension_size; + if (0 == _dwarf_string_valid(begin, end)) { + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD); + return (DW_DLV_ERROR); + } + } + *return_str = (char *) (begin); + return DW_DLV_OK; + } + + if (attr->ar_attribute_form == DW_FORM_strp) { + READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, + attr->ar_debug_info_ptr, + cu_context->cc_length_size); + + res = + _dwarf_load_section(dbg, + dbg->de_debug_str_index, + &dbg->de_debug_str, error); + if (res != DW_DLV_OK) { + return res; + } + + *return_str = (char *) (dbg->de_debug_str + offset); + return DW_DLV_OK; + } + + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,2359 @@ +/* + + Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include +#include "dwarf_frame.h" +#include "dwarf_arange.h" /* Using Arange as a way to build a + list */ + +#define FDE_NULL_CHECKS_AND_SET_DBG(fde,dbg ) \ + do { \ + if ((fde) == NULL) { \ + _dwarf_error(NULL, error, DW_DLE_FDE_NULL); \ + return (DW_DLV_ERROR); \ + } \ + (dbg)= (fde)->fd_dbg; \ + if ((dbg) == NULL) { \ + _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);\ + return (DW_DLV_ERROR); \ + } } while (0) + + +#define MIN(a,b) (((a) < (b))? a:b) + +static void _dwarf_init_regrule_table(struct Dwarf_Reg_Rule_s *t1reg, + int last_reg_num, + int initial_value); +static int dwarf_initialize_fde_table(Dwarf_Debug dbg, + struct Dwarf_Frame_s *fde_table, + unsigned table_real_data_size, + Dwarf_Error * error); +static void dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table); + +#if 0 +/* Only used for debugging libdwarf. */ +static void dump_frame_rule(char *msg, + struct Dwarf_Reg_Rule_s *reg_rule); +#endif + + + +/* + This function is the heart of the debug_frame stuff. Don't even + think of reading this without reading both the Libdwarf and + consumer API carefully first. This function basically executes + frame instructions contained in a Cie or an Fde, but does in a + number of different ways depending on the information sought. + Start_instr_ptr points to the first byte of the frame instruction + stream, and final_instr_ptr to the to the first byte after the + last. + + The offsets returned in the frame instructions are factored. That + is they need to be multiplied by either the code_alignment_factor + or the data_alignment_factor, as appropriate to obtain the actual + offset. This makes it possible to expand an instruction stream + without the corresponding Cie. However, when an Fde frame instr + sequence is being expanded there must be a valid Cie with a pointer + to an initial table row. + + + If successful, returns DW_DLV_OK + And sets returned_count thru the pointer + if make_instr is true. + If make_instr is false returned_count + should NOT be used by the caller (returned_count + is set to 0 thru the pointer by this routine...) + If unsuccessful, returns DW_DLV_ERROR + and sets returned_error to the error code + + It does not do a whole lot of input validation being a private + function. Please make sure inputs are valid. + + (1) If make_instr is true, it makes a list of pointers to + Dwarf_Frame_Op structures containing the frame instructions + executed. A pointer to this list is returned in ret_frame_instr. + Make_instr is true only when a list of frame instructions is to be + returned. In this case since we are not interested in the contents + of the table, the input Cie can be NULL. This is the only case + where the inpute Cie can be NULL. + + (2) If search_pc is true, frame instructions are executed till + either a location is reached that is greater than the search_pc_val + provided, or all instructions are executed. At this point the + last row of the table generated is returned in a structure. + A pointer to this structure is supplied in table. + + (3) This function is also used to create the initial table row + defined by a Cie. In this case, the Dwarf_Cie pointer cie, is + NULL. For an FDE, however, cie points to the associated Cie. + + make_instr - make list of frame instr? 0/1 + ret_frame_instr - Ptr to list of ptrs to frame instrs + search_pc - Search for a pc value? 0/1 + search_pc_val - Search for this pc value + initial_loc - Initial code location value. + start_instr_ptr - Ptr to start of frame instrs. + final_instr_ptr - Ptr just past frame instrs. + table - Ptr to struct with last row. + cie - Ptr to Cie used by the Fde. + +*/ + +int +_dwarf_exec_frame_instr(Dwarf_Bool make_instr, + Dwarf_Frame_Op ** ret_frame_instr, + Dwarf_Bool search_pc, + Dwarf_Addr search_pc_val, + Dwarf_Addr initial_loc, + Dwarf_Small * start_instr_ptr, + Dwarf_Small * final_instr_ptr, + Dwarf_Frame table, + Dwarf_Cie cie, + Dwarf_Debug dbg, + Dwarf_Half reg_num_of_cfa, + Dwarf_Sword * returned_count, + int *returned_error) +{ +#define ERROR_IF_REG_NUM_TOO_HIGH(macreg,machigh_reg) \ + do { \ + if ((macreg) >= (machigh_reg) || (macreg) < 0) { \ + SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH); \ + } \ + } /*CONSTCOND */ while(0) +#define SIMPLE_ERROR_RETURN(code) \ + free(localregtab); \ + *returned_error = code; \ + return DW_DLV_ERROR + + /* Sweeps the frame instructions. */ + Dwarf_Small *instr_ptr; + + /* Register numbers not limited to just 255, thus not using + Dwarf_Small. */ + typedef int reg_num_type; + + Dwarf_Unsigned factored_N_value; + Dwarf_Signed signed_factored_N_value; + Dwarf_Addr current_loc = initial_loc; /* code location/ + pc-value + corresponding to the + frame instructions. + Starts at zero when + the caller has no + value to pass in. */ + + /* Must be min de_pointer_size bytes and must be at least sizeof + Dwarf_ufixed */ + Dwarf_Unsigned adv_loc; + + int reg_count = dbg->de_frame_reg_rules_entry_count; + struct Dwarf_Reg_Rule_s *localregtab = calloc(reg_count, + sizeof(struct + Dwarf_Reg_Rule_s)); + + struct Dwarf_Reg_Rule_s cfa_reg; + + + /* This is used to end executing frame instructions. */ + /* Becomes true when search_pc is true and current_loc */ + /* is greater than search_pc_val. */ + Dwarf_Bool search_over = false; + + /* Used by the DW_FRAME_advance_loc instr */ + /* to hold the increment in pc value. */ + Dwarf_Addr adv_pc; + + /* Contains the length in bytes of */ + /* an leb128 encoded number. */ + Dwarf_Word leb128_length; + + /* Counts the number of frame instructions executed. */ + Dwarf_Word instr_count = 0; + + /* + These contain the current fields of the current frame + instruction. */ + Dwarf_Small fp_base_op = 0; + Dwarf_Small fp_extended_op; + reg_num_type fp_register; + + /* The value in fp_offset may be signed, though we call it + unsigned. This works ok for 2-s complement arithmetic. */ + Dwarf_Unsigned fp_offset; + Dwarf_Off fp_instr_offset; + + /* + Stack_table points to the row (Dwarf_Frame ie) being pushed or + popped by a remember or restore instruction. Top_stack points to + the top of the stack of rows. */ + Dwarf_Frame stack_table; + Dwarf_Frame top_stack = NULL; + + /* + These are used only when make_instr is true. Curr_instr is a + pointer to the current frame instruction executed. + Curr_instr_ptr, head_instr_list, and curr_instr_list are used to + form a chain of Dwarf_Frame_Op structs. Dealloc_instr_ptr is + used to deallocate the structs used to form the chain. + Head_instr_block points to a contiguous list of pointers to the + Dwarf_Frame_Op structs executed. */ + Dwarf_Frame_Op *curr_instr; + Dwarf_Chain curr_instr_item, dealloc_instr_item; + Dwarf_Chain head_instr_chain = NULL; + Dwarf_Chain tail_instr_chain = NULL; + Dwarf_Frame_Op *head_instr_block; + + /* + These are the alignment_factors taken from the Cie provided. + When no input Cie is provided they are set to 1, because only + factored offsets are required. */ + Dwarf_Sword code_alignment_factor = 1; + Dwarf_Sword data_alignment_factor = 1; + + /* + This flag indicates when an actual alignment factor is needed. + So if a frame instruction that computes an offset using an + alignment factor is encountered when this flag is set, an error + is returned because the Cie did not have a valid augmentation. */ + Dwarf_Bool need_augmentation = false; + + Dwarf_Word i; + + /* Initialize first row from associated Cie. Using temp regs + explicity */ + + + if (localregtab == 0) { + SIMPLE_ERROR_RETURN(DW_DLE_ALLOC_FAIL); + } + { + struct Dwarf_Reg_Rule_s *t1reg = localregtab; + struct Dwarf_Reg_Rule_s *t1end = t1reg + reg_count; + + if (cie != NULL && cie->ci_initial_table != NULL) { + struct Dwarf_Reg_Rule_s *t2reg = + cie->ci_initial_table->fr_reg; + + if (reg_count != cie->ci_initial_table->fr_reg_count) { + /* Should never happen, it makes no sense to have the + table sizes change. There is no real allowance for + the set of registers to change dynamically in a + single Dwarf_Debug (except the size can be set near + initial Dwarf_Debug creation time). */ + SIMPLE_ERROR_RETURN + (DW_DLE_FRAME_REGISTER_COUNT_MISMATCH); + } + + for (; t1reg < t1end; t1reg++, t2reg++) { + *t1reg = *t2reg; + } + cfa_reg = cie->ci_initial_table->fr_cfa_rule; + } else { + _dwarf_init_regrule_table(t1reg, + reg_count, + dbg->de_frame_rule_initial_value); + _dwarf_init_regrule_table(&cfa_reg, 1, + dbg->de_frame_rule_initial_value); + } + } + + /* + The idea here is that the code_alignment_factor and + data_alignment_factor which are needed for certain instructions + are valid only when the Cie has a proper augmentation string. So + if the augmentation is not right, only Frame instruction can be + read. */ + if (cie != NULL && cie->ci_augmentation != NULL) { + code_alignment_factor = cie->ci_code_alignment_factor; + data_alignment_factor = cie->ci_data_alignment_factor; + } else { + need_augmentation = !make_instr; + } + + instr_ptr = start_instr_ptr; + while ((instr_ptr < final_instr_ptr) && (!search_over)) { + Dwarf_Small instr = 0; + Dwarf_Small opcode = 0; + reg_num_type reg_no = 0; + + + fp_instr_offset = instr_ptr - start_instr_ptr; + instr = *(Dwarf_Small *) instr_ptr; + instr_ptr += sizeof(Dwarf_Small); + + fp_base_op = (instr & 0xc0) >> 6; + if ((instr & 0xc0) == 0x00) { + opcode = instr; /* is really extended op */ + fp_extended_op = (instr & (~(0xc0))) & 0xff; + } else { + opcode = instr & 0xc0; /* is base op */ + fp_extended_op = 0; + } + + fp_register = 0; + fp_offset = 0; + switch (opcode) { + case DW_CFA_advance_loc: + { + /* base op */ + fp_offset = adv_pc = instr & DW_FRAME_INSTR_OFFSET_MASK; + + if (need_augmentation) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); + } + adv_pc = adv_pc * code_alignment_factor; + + search_over = search_pc && + (current_loc + adv_pc > search_pc_val); + /* If gone past pc needed, retain old pc. */ + if (!search_over) + current_loc = current_loc + adv_pc; + break; + } + + case DW_CFA_offset: + { /* base op */ + reg_no = + (reg_num_type) (instr & DW_FRAME_INSTR_OFFSET_MASK); + ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); + + factored_N_value = + _dwarf_decode_u_leb128(instr_ptr, &leb128_length); + instr_ptr = instr_ptr + leb128_length; + + fp_register = reg_no; + fp_offset = factored_N_value; + + if (need_augmentation) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); + } + + localregtab[reg_no].ru_is_off = 1; + localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET; + localregtab[reg_no].ru_register = reg_num_of_cfa; + localregtab[reg_no].ru_offset_or_block_len = + factored_N_value * data_alignment_factor; + + break; + } + + case DW_CFA_restore: + { /* base op */ + reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK); + ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); + + fp_register = reg_no; + + if (cie != NULL && cie->ci_initial_table != NULL) + localregtab[reg_no] = + cie->ci_initial_table->fr_reg[reg_no]; + else if (!make_instr) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_MAKE_INSTR_NO_INIT); + } + + break; + } + case DW_CFA_set_loc: + { + Dwarf_Addr new_loc = 0; + + READ_UNALIGNED(dbg, new_loc, Dwarf_Addr, + instr_ptr, dbg->de_pointer_size); + instr_ptr += dbg->de_pointer_size; + if (new_loc != 0 && current_loc != 0) { + /* Pre-relocation or before current_loc is set the + test comparing new_loc and current_loc makes no + sense. Testing for non-zero (above) is a way + (fallible) to check that current_loc, new_loc + are already relocated. */ + if (new_loc <= current_loc) { + /* Within a frame, address must increase. + Seemingly it has not. Seems to be an error. */ + + SIMPLE_ERROR_RETURN + (DW_DLE_DF_NEW_LOC_LESS_OLD_LOC); + } + } + + search_over = search_pc && (new_loc > search_pc_val); + + /* If gone past pc needed, retain old pc. */ + if (!search_over) + current_loc = new_loc; + fp_offset = new_loc; + break; + } + + case DW_CFA_advance_loc1: + { + fp_offset = adv_loc = *(Dwarf_Small *) instr_ptr; + instr_ptr += sizeof(Dwarf_Small); + + if (need_augmentation) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); + } + adv_loc *= code_alignment_factor; + + search_over = search_pc && + (current_loc + adv_loc > search_pc_val); + + /* If gone past pc needed, retain old pc. */ + if (!search_over) + current_loc = current_loc + adv_loc; + break; + } + + case DW_CFA_advance_loc2: + { + READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned, + instr_ptr, sizeof(Dwarf_Half)); + instr_ptr += sizeof(Dwarf_Half); + fp_offset = adv_loc; + + if (need_augmentation) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); + } + adv_loc *= code_alignment_factor; + + search_over = search_pc && + (current_loc + adv_loc > search_pc_val); + + /* If gone past pc needed, retain old pc. */ + if (!search_over) + current_loc = current_loc + adv_loc; + break; + } + + case DW_CFA_advance_loc4: + { + READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned, + instr_ptr, sizeof(Dwarf_ufixed)); + instr_ptr += sizeof(Dwarf_ufixed); + fp_offset = adv_loc; + + if (need_augmentation) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); + } + adv_loc *= code_alignment_factor; + + search_over = search_pc && + (current_loc + adv_loc > search_pc_val); + + /* If gone past pc needed, retain old pc. */ + if (!search_over) + current_loc = current_loc + adv_loc; + break; + } + + case DW_CFA_offset_extended: + { + Dwarf_Unsigned lreg; + + DECODE_LEB128_UWORD(instr_ptr, lreg); + reg_no = (reg_num_type) lreg; + ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);; + factored_N_value = + _dwarf_decode_u_leb128(instr_ptr, &leb128_length); + instr_ptr += leb128_length; + + if (need_augmentation) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); + } + localregtab[reg_no].ru_is_off = 1; + localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET; + localregtab[reg_no].ru_register = reg_num_of_cfa; + localregtab[reg_no].ru_offset_or_block_len = factored_N_value * + data_alignment_factor; + + fp_register = reg_no; + fp_offset = factored_N_value; + break; + } + + case DW_CFA_restore_extended: + { + Dwarf_Unsigned lreg; + + DECODE_LEB128_UWORD(instr_ptr, lreg); + reg_no = (reg_num_type) lreg; + + ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); + + if (cie != NULL && cie->ci_initial_table != NULL) { + localregtab[reg_no] = cie->ci_initial_table->fr_reg[reg_no]; + } else { + if (!make_instr) { + SIMPLE_ERROR_RETURN + (DW_DLE_DF_MAKE_INSTR_NO_INIT); + } + } + + fp_register = reg_no; + break; + } + + case DW_CFA_undefined: + { + Dwarf_Unsigned lreg; + + DECODE_LEB128_UWORD(instr_ptr, lreg); + reg_no = (reg_num_type) lreg; + ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); + + localregtab[reg_no].ru_is_off = 0; + localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET; + localregtab[reg_no].ru_register = DW_FRAME_UNDEFINED_VAL; + localregtab[reg_no].ru_offset_or_block_len = 0; + + fp_register = reg_no; + break; + } + + case DW_CFA_same_value: + { + Dwarf_Unsigned lreg; + + DECODE_LEB128_UWORD(instr_ptr, lreg); + reg_no = (reg_num_type) lreg; + ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); + + localregtab[reg_no].ru_is_off = 0; + localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET; + localregtab[reg_no].ru_register = DW_FRAME_SAME_VAL; + localregtab[reg_no].ru_offset_or_block_len = 0; + fp_register = reg_no; + break; + } + + case DW_CFA_register: + { + Dwarf_Unsigned lreg; + reg_num_type reg_noA = 0; + reg_num_type reg_noB = 0; + + DECODE_LEB128_UWORD(instr_ptr, lreg); + reg_noA = (reg_num_type) lreg; + + ERROR_IF_REG_NUM_TOO_HIGH(reg_noA, reg_count); + + DECODE_LEB128_UWORD(instr_ptr, lreg); + reg_noB = (reg_num_type) lreg; + + if (reg_noB > reg_count) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH); + } + + + localregtab[reg_noA].ru_is_off = 0; + localregtab[reg_noA].ru_value_type = DW_EXPR_OFFSET; + localregtab[reg_noA].ru_register = reg_noB; + localregtab[reg_noA].ru_offset_or_block_len = 0; + + fp_register = reg_noA; + fp_offset = reg_noB; + break; + } + + case DW_CFA_remember_state: + { + stack_table = (Dwarf_Frame) + _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1); + if (stack_table == NULL) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL); + } + + for (i = 0; i < reg_count; i++) + stack_table->fr_reg[i] = localregtab[i]; + + if (top_stack != NULL) + stack_table->fr_next = top_stack; + top_stack = stack_table; + + break; + } + + case DW_CFA_restore_state: + { + if (top_stack == NULL) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_POP_EMPTY_STACK); + } + stack_table = top_stack; + top_stack = stack_table->fr_next; + + for (i = 0; i < reg_count; i++) + localregtab[i] = stack_table->fr_reg[i]; + + dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME); + break; + } + + case DW_CFA_def_cfa: + { + Dwarf_Unsigned lreg; + + DECODE_LEB128_UWORD(instr_ptr, lreg); + reg_no = (reg_num_type) lreg; + + ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); + + factored_N_value = + _dwarf_decode_u_leb128(instr_ptr, &leb128_length); + instr_ptr += leb128_length; + + if (need_augmentation) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); + } + cfa_reg.ru_is_off = 1; + cfa_reg.ru_value_type = DW_EXPR_OFFSET; + cfa_reg.ru_register = reg_no; + cfa_reg.ru_offset_or_block_len = factored_N_value; + + fp_register = reg_no; + fp_offset = factored_N_value; + break; + } + + case DW_CFA_def_cfa_register: + { + Dwarf_Unsigned lreg; + + DECODE_LEB128_UWORD(instr_ptr, lreg); + reg_no = (reg_num_type) lreg; + ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); + + cfa_reg.ru_register = reg_no; + /* Do NOT set ru_offset_or_block_len or ru_is_off here. + See dwarf2/3 spec. */ + fp_register = reg_no; + break; + } + + case DW_CFA_def_cfa_offset: + { + factored_N_value = + _dwarf_decode_u_leb128(instr_ptr, &leb128_length); + instr_ptr += leb128_length; + + if (need_augmentation) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); + } + /* Do set ru_is_off here, as here factored_N_value + counts. */ + cfa_reg.ru_is_off = 1; + cfa_reg.ru_value_type = DW_EXPR_OFFSET; + cfa_reg.ru_offset_or_block_len = factored_N_value; + + fp_offset = factored_N_value; + break; + } + case DW_CFA_nop: + { + break; + } + /* DWARF3 ops begin here. */ + case DW_CFA_def_cfa_expression: + { + /* A single DW_FORM_block representing a dwarf + expression. The form block establishes the way to + compute the CFA. */ + Dwarf_Unsigned block_len = 0; + + DECODE_LEB128_UWORD(instr_ptr, block_len); + cfa_reg.ru_is_off = 0; /* arbitrary */ + cfa_reg.ru_value_type = DW_EXPR_EXPRESSION; + cfa_reg.ru_offset_or_block_len = block_len; + cfa_reg.ru_block = instr_ptr; + fp_offset = (Dwarf_Unsigned) instr_ptr; + + } + break; + case DW_CFA_expression: + { + /* An unsigned leb128 value is the first operand (a + register number). The second operand is single + DW_FORM_block representing a dwarf expression. The + evaluator pushes the CFA on the evaluation stack + then evaluates the expression to compute the value + of the register contents. */ + Dwarf_Unsigned lreg = 0; + Dwarf_Unsigned block_len = 0; + + DECODE_LEB128_UWORD(instr_ptr, lreg); + reg_no = (reg_num_type) lreg; + ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); + DECODE_LEB128_UWORD(instr_ptr, block_len); + localregtab[lreg].ru_is_off = 0; /* arbitrary */ + localregtab[lreg].ru_value_type = DW_EXPR_EXPRESSION; + localregtab[lreg].ru_offset_or_block_len = block_len; + localregtab[lreg].ru_block = instr_ptr; + fp_offset = (Dwarf_Unsigned) instr_ptr; + fp_register = reg_no; + + } + break; + case DW_CFA_cfa_offset_extended_sf: + { + /* The first operand is an unsigned leb128 register + number. The second is a signed factored offset. + Identical to DW_CFA_offset_extended except the + secondoperand is signed */ + Dwarf_Unsigned lreg; + + DECODE_LEB128_UWORD(instr_ptr, lreg); + reg_no = (reg_num_type) lreg; + ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); + signed_factored_N_value = + _dwarf_decode_s_leb128(instr_ptr, &leb128_length); + instr_ptr += leb128_length; + + if (need_augmentation) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); + } + localregtab[reg_no].ru_is_off = 1; + localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET; + localregtab[reg_no].ru_register = reg_num_of_cfa; + localregtab[reg_no].ru_offset_or_block_len = + signed_factored_N_value * data_alignment_factor; + + fp_register = reg_no; + fp_offset = signed_factored_N_value; + } + break; + case DW_CFA_def_cfa_sf: + { + /* The first operand is an unsigned leb128 register + number. The second is a signed leb128 factored + offset. Identical to DW_CFA_def_cfa except that the + second operand is signed and factored. */ + Dwarf_Unsigned lreg; + + DECODE_LEB128_UWORD(instr_ptr, lreg); + reg_no = (reg_num_type) lreg; + ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); + + signed_factored_N_value = + _dwarf_decode_s_leb128(instr_ptr, &leb128_length); + instr_ptr += leb128_length; + + if (need_augmentation) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); + } + cfa_reg.ru_is_off = 1; + cfa_reg.ru_value_type = DW_EXPR_OFFSET; + cfa_reg.ru_register = reg_no; + cfa_reg.ru_offset_or_block_len = + signed_factored_N_value * data_alignment_factor; + + fp_register = reg_no; + fp_offset = signed_factored_N_value; + } + break; + case DW_CFA_def_cfa_offset_sf: + { + /* The operand is a signed leb128 operand representing + a factored offset. Identical to + DW_CFA_def_cfa_offset excep the operand is signed + and factored. */ + + signed_factored_N_value = + _dwarf_decode_s_leb128(instr_ptr, &leb128_length); + instr_ptr += leb128_length; + + if (need_augmentation) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); + } + /* Do set ru_is_off here, as here factored_N_value + counts. */ + cfa_reg.ru_is_off = 1; + cfa_reg.ru_value_type = DW_EXPR_OFFSET; + cfa_reg.ru_offset_or_block_len = + signed_factored_N_value * data_alignment_factor; + + fp_offset = signed_factored_N_value; + } + break; + case DW_CFA_val_offset: + { + /* The first operand is an unsigned leb128 register + number. The second is a factored unsigned offset. + Makes the register be a val_offset(N) rule with N = + factored_offset*data_alignment_factor. */ + + Dwarf_Unsigned lreg; + + DECODE_LEB128_UWORD(instr_ptr, lreg); + reg_no = (reg_num_type) lreg; + + ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); + + factored_N_value = + _dwarf_decode_u_leb128(instr_ptr, &leb128_length); + instr_ptr += leb128_length; + + if (need_augmentation) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); + } + /* Do set ru_is_off here, as here factored_N_value + counts. */ + localregtab[reg_no].ru_is_off = 1; + localregtab[reg_no].ru_register = reg_num_of_cfa; + localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET; + localregtab[reg_no].ru_offset_or_block_len = + factored_N_value * data_alignment_factor; + + fp_offset = factored_N_value; + break; + } + case DW_CFA_val_offset_sf: + { + /* The first operand is an unsigned leb128 register + number. The second is a factored signed offset. + Makes the register be a val_offset(N) rule with N = + factored_offset*data_alignment_factor. */ + Dwarf_Unsigned lreg; + + DECODE_LEB128_UWORD(instr_ptr, lreg); + reg_no = (reg_num_type) lreg; + + ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); + signed_factored_N_value = + _dwarf_decode_s_leb128(instr_ptr, &leb128_length); + instr_ptr += leb128_length; + + if (need_augmentation) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); + } + /* Do set ru_is_off here, as here factored_N_value + counts. */ + localregtab[reg_no].ru_is_off = 1; + localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET; + localregtab[reg_no].ru_offset_or_block_len = + signed_factored_N_value * data_alignment_factor; + + fp_offset = signed_factored_N_value; + + } + break; + case DW_CFA_val_expression: + { + /* The first operand is an unsigned leb128 register + number. The second is a DW_FORM_block representing a + DWARF expression. The rule for the register number + becomes a val_expression(E) rule. */ + Dwarf_Unsigned lreg = 0; + Dwarf_Unsigned block_len = 0; + + DECODE_LEB128_UWORD(instr_ptr, lreg); + reg_no = (reg_num_type) lreg; + ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); + DECODE_LEB128_UWORD(instr_ptr, block_len); + localregtab[lreg].ru_is_off = 0; /* arbitrary */ + localregtab[lreg].ru_value_type = DW_EXPR_VAL_EXPRESSION; + localregtab[lreg].ru_offset_or_block_len = block_len; + localregtab[lreg].ru_block = instr_ptr; + fp_offset = (Dwarf_Unsigned) instr_ptr; + + instr_ptr += block_len; + fp_register = reg_no; + + } + break; + + /* END DWARF3 new ops. */ + + +#ifdef DW_CFA_GNU_window_save + case DW_CFA_GNU_window_save: + { + /* no information: this just tells unwinder to restore + the window registers from the previous frame's + window save area */ + break; + } +#endif +#ifdef DW_CFA_GNU_args_size + /* single uleb128 is the current arg area size in bytes. No + register exists yet to save this in */ + case DW_CFA_GNU_args_size: + { + Dwarf_Unsigned lreg; + + DECODE_LEB128_UWORD(instr_ptr, lreg); + reg_no = (reg_num_type) lreg; + + break; + } +#endif + default: + /* ERROR, we have an opcode we know nothing about. Memory + leak here, but an error like this is not supposed to + happen so we ignore the leak. These used to be ignored, + now we notice and report. */ + SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR); + + } + + if (make_instr) { + instr_count++; + + curr_instr = (Dwarf_Frame_Op *) + _dwarf_get_alloc(dbg, DW_DLA_FRAME_OP, 1); + if (curr_instr == NULL) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL); + } + + curr_instr->fp_base_op = fp_base_op; + curr_instr->fp_extended_op = fp_extended_op; + curr_instr->fp_register = fp_register; + curr_instr->fp_offset = fp_offset; + curr_instr->fp_instr_offset = fp_instr_offset; + + curr_instr_item = (Dwarf_Chain) + _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (curr_instr_item == NULL) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL); + } + + curr_instr_item->ch_item = curr_instr; + if (head_instr_chain == NULL) + head_instr_chain = tail_instr_chain = curr_instr_item; + else { + tail_instr_chain->ch_next = curr_instr_item; + tail_instr_chain = curr_instr_item; + } + } + } + + /* + If frame instruction decoding was right we would stop exactly at + final_instr_ptr. */ + if (instr_ptr > final_instr_ptr) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR); + } + + /* Create the last row generated. */ + if (table != NULL) { + + struct Dwarf_Reg_Rule_s *t2reg = table->fr_reg; + struct Dwarf_Reg_Rule_s *t3reg = localregtab; + struct Dwarf_Reg_Rule_s *t3end = t3reg + reg_count; + + table->fr_loc = current_loc; + for (; t3reg < t3end; t3reg++, t2reg++) { + *t2reg = *t3reg; + } + + /* CONSTCOND */ + if (reg_num_of_cfa < reg_count) { + t2reg = table->fr_reg + reg_num_of_cfa; + /* Update both the old DW_FRAME_CFA_COL row and the new + fr_cfa_rule with the cfa_reg, this is the old-style + update. */ + *t2reg = cfa_reg; + } + table->fr_cfa_rule = cfa_reg; + } + + /* Dealloc anything remaining on stack. */ + for (; top_stack != NULL;) { + stack_table = top_stack; + top_stack = top_stack->fr_next; + dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME); + } + + if (make_instr) { + /* Allocate list of pointers to Dwarf_Frame_Op's. */ + head_instr_block = (Dwarf_Frame_Op *) + _dwarf_get_alloc(dbg, DW_DLA_FRAME_BLOCK, instr_count); + if (head_instr_block == NULL) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL); + } + + /* + Store pointers to Dwarf_Frame_Op's in this list and + deallocate the structs that chain the Dwarf_Frame_Op's. */ + curr_instr_item = head_instr_chain; + for (i = 0; i < instr_count; i++) { + *(head_instr_block + i) = + *(Dwarf_Frame_Op *) curr_instr_item->ch_item; + dealloc_instr_item = curr_instr_item; + curr_instr_item = curr_instr_item->ch_next; + dwarf_dealloc(dbg, dealloc_instr_item->ch_item, + DW_DLA_FRAME_OP); + dwarf_dealloc(dbg, dealloc_instr_item, DW_DLA_CHAIN); + } + *ret_frame_instr = head_instr_block; + + *returned_count = (Dwarf_Sword) instr_count; + } else { + *returned_count = 0; + } + free(localregtab); + return DW_DLV_OK; +#undef ERROR_IF_REG_NUM_TOO_HIGH +#undef SIMPLE_ERROR_RETURN +} + +/* Depending on version, either read the return address register + as a ubyte or as an leb number. + The form of this value changed for DWARF3. +*/ +Dwarf_Unsigned +_dwarf_get_return_address_reg(Dwarf_Small * frame_ptr, + int version, unsigned long *size) +{ + Dwarf_Unsigned uvalue = 0; + Dwarf_Word leb128_length = 0; + + if (version == 1) { + *size = 1; + uvalue = *(unsigned char *) frame_ptr; + return uvalue; + } + uvalue = _dwarf_decode_u_leb128(frame_ptr, &leb128_length); + *size = leb128_length; + return uvalue; +} + + +/* Trivial consumer function. +*/ +int +dwarf_get_cie_of_fde(Dwarf_Fde fde, + Dwarf_Cie * cie_returned, Dwarf_Error * error) +{ + if (fde == NULL) { + _dwarf_error(NULL, error, DW_DLE_FDE_NULL); + return (DW_DLV_ERROR); + } + + *cie_returned = fde->fd_cie; + return DW_DLV_OK; + +} + +/* + For g++ .eh_frame fde and cie. + the cie id is different as the + definition of the cie_id in an fde + is the distance back from the address of the + value to the cie. + Or 0 if this is a true cie. + Non standard dwarf, designed this way to be + convenient at run time for an allocated + (mapped into memory as part of the running image) section. +*/ +int +dwarf_get_fde_list_eh(Dwarf_Debug dbg, + Dwarf_Cie ** cie_data, + Dwarf_Signed * cie_element_count, + Dwarf_Fde ** fde_data, + Dwarf_Signed * fde_element_count, + Dwarf_Error * error) +{ + int res; + + res = + _dwarf_load_section(dbg, + dbg->de_debug_frame_eh_gnu_index, + &dbg->de_debug_frame_eh_gnu, error); + + if (res != DW_DLV_OK) { + return res; + } + + res = + _dwarf_get_fde_list_internal(dbg, + cie_data, + cie_element_count, + fde_data, + fde_element_count, + dbg->de_debug_frame_eh_gnu, + dbg->de_debug_frame_eh_gnu_index, + dbg->de_debug_frame_size_eh_gnu, + /* cie_id_value */ 0, + /* use_gnu_cie_calc= */ 1, + error); + return res; +} + + + +/* + For standard dwarf .debug_frame + cie_id is -1 in a cie, and + is the section offset in the .debug_frame section + of the cie otherwise. Standard dwarf +*/ +int +dwarf_get_fde_list(Dwarf_Debug dbg, + Dwarf_Cie ** cie_data, + Dwarf_Signed * cie_element_count, + Dwarf_Fde ** fde_data, + Dwarf_Signed * fde_element_count, + Dwarf_Error * error) +{ + int res; + + res = + _dwarf_load_section(dbg, + dbg->de_debug_frame_index, + &dbg->de_debug_frame, error); + + if (res != DW_DLV_OK) { + return res; + } + + res = + _dwarf_get_fde_list_internal(dbg, cie_data, + cie_element_count, + fde_data, + fde_element_count, + dbg->de_debug_frame, + dbg->de_debug_frame_index, + dbg->de_debug_frame_size, + DW_CIE_ID, + /* use_gnu_cie_calc= */ 0, + error); + + return res; +} + + +/* + Only works on dwarf sections, not eh_frame + Given a Dwarf_Die, see if it has a + DW_AT_MIPS_fde attribute and if so use that + to get an fde offset. + Then create a Dwarf_Fde to return thru the ret_fde pointer. + Also creates a cie (pointed at from the Dwarf_Fde). +*/ +int +dwarf_get_fde_for_die(Dwarf_Debug dbg, + Dwarf_Die die, + Dwarf_Fde * ret_fde, Dwarf_Error * error) +{ + Dwarf_Attribute attr; + Dwarf_Unsigned fde_offset = 0; + Dwarf_Signed signdval = 0; + Dwarf_Fde new_fde = 0; + unsigned char *fde_ptr = 0; + unsigned char *cie_ptr = 0; + Dwarf_Unsigned cie_id = 0; + + /* Fields for the current Cie being read. */ + int res; + int resattr; + int sdatares; + + struct cie_fde_prefix_s prefix; + struct cie_fde_prefix_s prefix_c; + + if (die == NULL) { + _dwarf_error(NULL, error, DW_DLE_DIE_NULL); + return (DW_DLV_ERROR); + } + + resattr = dwarf_attr(die, DW_AT_MIPS_fde, &attr, error); + if (resattr != DW_DLV_OK) { + return resattr; + } + + /* why is this formsdata? FIX */ + sdatares = dwarf_formsdata(attr, &signdval, error); + if (sdatares != DW_DLV_OK) { + return sdatares; + } + + res = + _dwarf_load_section(dbg, + dbg->de_debug_frame_index, + &dbg->de_debug_frame, error); + if (res != DW_DLV_OK) { + return res; + } + + fde_offset = signdval; + fde_ptr = (dbg->de_debug_frame + fde_offset); + + + /* First read in the 'common prefix' to figure out what * we are to + do with this entry. */ + memset(&prefix_c, 0, sizeof(prefix_c)); + memset(&prefix, 0, sizeof(prefix)); + res = dwarf_read_cie_fde_prefix(dbg, fde_ptr, + dbg->de_debug_frame, + dbg->de_debug_frame_index, + dbg->de_debug_frame_size, &prefix, + error); + if (res == DW_DLV_ERROR) { + return res; + } + if (res == DW_DLV_NO_ENTRY) + return res; + fde_ptr = prefix.cf_addr_after_prefix; + cie_id = prefix.cf_cie_id; + /* Pass NULL, not section pointer, for 3rd argument. de_debug_frame + has no eh_frame relevance. */ + res = dwarf_create_fde_from_after_start(dbg, &prefix, + (Dwarf_Small *) NULL, + fde_ptr, + /* use_gnu_cie_calc= */ 0, + /* Dwarf_Cie = */ 0, + &new_fde, error); + + if (res == DW_DLV_ERROR) { + return res; + } else if (res == DW_DLV_NO_ENTRY) { + return res; + } + /* DW_DLV_OK */ + + /* now read the cie corresponding to the fde */ + cie_ptr = new_fde->fd_section_ptr + cie_id; + res = dwarf_read_cie_fde_prefix(dbg, cie_ptr, + dbg->de_debug_frame, + dbg->de_debug_frame_index, + dbg->de_debug_frame_size, + &prefix_c, error); + if (res == DW_DLV_ERROR) { + return res; + } + if (res == DW_DLV_NO_ENTRY) + return res; + + cie_ptr = prefix_c.cf_addr_after_prefix; + cie_id = prefix_c.cf_cie_id; + + + if (cie_id == DW_CIE_ID) { + int res2 = 0; + Dwarf_Cie new_cie = 0; + + /* Pass NULL, not section pointer, for 3rd argument. + de_debug_frame has no eh_frame relevance. */ + res2 = dwarf_create_cie_from_after_start(dbg, + &prefix_c, + (Dwarf_Small *) NULL, + cie_ptr, + /* cie_count= */ 0, + /* use_gnu_cie_calc= */ + 0, &new_cie, error); + if (res2 == DW_DLV_ERROR) { + dwarf_dealloc(dbg, new_fde, DW_DLA_FDE); + return res; + } else if (res2 == DW_DLV_NO_ENTRY) { + dwarf_dealloc(dbg, new_fde, DW_DLA_FDE); + return res; + } + + + new_fde->fd_cie = new_cie; + + } else { + _dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE); + return (DW_DLV_ERROR); + } + + *ret_fde = new_fde; + return DW_DLV_OK; +} + +/* A dwarf consumer operation, see the consumer library documentation. +*/ +int +dwarf_get_fde_range(Dwarf_Fde fde, + Dwarf_Addr * low_pc, + Dwarf_Unsigned * func_length, + Dwarf_Ptr * fde_bytes, + Dwarf_Unsigned * fde_byte_length, + Dwarf_Off * cie_offset, + Dwarf_Signed * cie_index, + Dwarf_Off * fde_offset, Dwarf_Error * error) +{ + Dwarf_Debug dbg; + + if (fde == NULL) { + _dwarf_error(NULL, error, DW_DLE_FDE_NULL); + return (DW_DLV_ERROR); + } + + dbg = fde->fd_dbg; + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); + return (DW_DLV_ERROR); + } + + + /* We have always already done the section load here, so no need to + load the section. We did the section load in order to create the + Dwarf_Fde pointer passed in here. */ + + + if (low_pc != NULL) + *low_pc = fde->fd_initial_location; + if (func_length != NULL) + *func_length = fde->fd_address_range; + if (fde_bytes != NULL) + *fde_bytes = fde->fd_fde_start; + if (fde_byte_length != NULL) + *fde_byte_length = fde->fd_length; + if (cie_offset != NULL) + *cie_offset = fde->fd_cie_offset; + if (cie_index != NULL) + *cie_index = fde->fd_cie_index; + if (fde_offset != NULL) + *fde_offset = fde->fd_fde_start - fde->fd_section_ptr; + + return DW_DLV_OK; +} + +/* IRIX specific function. The exception tables + have C++ destructor information and are + at present undocumented. */ +int +dwarf_get_fde_exception_info(Dwarf_Fde fde, + Dwarf_Signed * + offset_into_exception_tables, + Dwarf_Error * error) +{ + Dwarf_Debug dbg; + + dbg = fde->fd_dbg; + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); + return (DW_DLV_ERROR); + } + *offset_into_exception_tables = + fde->fd_offset_into_exception_tables; + return DW_DLV_OK; +} + + +/* A consumer code function. + Given a CIE pointer, return the normal CIE data thru + pointers. + Special augmentation data is not returned here. +*/ +int +dwarf_get_cie_info(Dwarf_Cie cie, + Dwarf_Unsigned * bytes_in_cie, + Dwarf_Small * ptr_to_version, + char **augmenter, + Dwarf_Unsigned * code_alignment_factor, + Dwarf_Signed * data_alignment_factor, + Dwarf_Half * return_address_register, + Dwarf_Ptr * initial_instructions, + Dwarf_Unsigned * initial_instructions_length, + Dwarf_Error * error) +{ + Dwarf_Debug dbg; + + if (cie == NULL) { + _dwarf_error(NULL, error, DW_DLE_CIE_NULL); + return (DW_DLV_ERROR); + } + + dbg = cie->ci_dbg; + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_CIE_DBG_NULL); + return (DW_DLV_ERROR); + } + + if (ptr_to_version != NULL) + *ptr_to_version = cie->ci_cie_version_number; + if (augmenter != NULL) + *augmenter = cie->ci_augmentation; + if (code_alignment_factor != NULL) + *code_alignment_factor = cie->ci_code_alignment_factor; + if (data_alignment_factor != NULL) + *data_alignment_factor = cie->ci_data_alignment_factor; + if (return_address_register != NULL) + *return_address_register = cie->ci_return_address_register; + if (initial_instructions != NULL) + *initial_instructions = cie->ci_cie_instr_start; + if (initial_instructions_length != NULL) { + *initial_instructions_length = cie->ci_length + + cie->ci_length_size + + cie->ci_extension_size - + (cie->ci_cie_instr_start - cie->ci_cie_start); + + } + *bytes_in_cie = (cie->ci_length); + return (DW_DLV_OK); +} + +/* Return the register rules for all registers at a given pc. +*/ +static int +_dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde, + Dwarf_Addr pc_requested, + Dwarf_Frame table, + Dwarf_Half cfa_reg_col_num, + Dwarf_Error * error) +{ + Dwarf_Debug dbg = 0; + Dwarf_Cie cie = 0; + int dw_err = 0; + Dwarf_Sword icount = 0; + int res = 0; + + if (fde == NULL) { + _dwarf_error(NULL, error, DW_DLE_FDE_NULL); + return (DW_DLV_ERROR); + } + + dbg = fde->fd_dbg; + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); + return (DW_DLV_ERROR); + } + + if (pc_requested < fde->fd_initial_location || + pc_requested >= + fde->fd_initial_location + fde->fd_address_range) { + _dwarf_error(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); + return (DW_DLV_ERROR); + } + + cie = fde->fd_cie; + if (cie->ci_initial_table == NULL) { + cie->ci_initial_table = _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1); + + if (cie->ci_initial_table == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + _dwarf_init_regrule_table(cie->ci_initial_table->fr_reg, + dbg->de_frame_reg_rules_entry_count, + dbg->de_frame_rule_initial_value); + _dwarf_init_regrule_table(&cie->ci_initial_table->fr_cfa_rule, + 1, dbg->de_frame_rule_initial_value); + res = _dwarf_exec_frame_instr( /* make_instr= */ false, + /* ret_frame_instr= */ NULL, + /* search_pc */ false, + /* search_pc_val */ 0, + /* location */ 0, + cie->ci_cie_instr_start, + cie->ci_cie_instr_start + + (cie->ci_length + + cie->ci_length_size + + cie->ci_extension_size - + (cie->ci_cie_instr_start - + cie->ci_cie_start)), + cie->ci_initial_table, cie, dbg, + cfa_reg_col_num, &icount, + &dw_err); + if (res == DW_DLV_ERROR) { + _dwarf_error(dbg, error, dw_err); + return (res); + } else if (res == DW_DLV_NO_ENTRY) { + return res; + } + } + + { + Dwarf_Small *instr_end = fde->fd_fde_instr_start + + fde->fd_length + + fde->fd_length_size + + fde->fd_extension_size - (fde->fd_fde_instr_start - + fde->fd_fde_start); + + res = _dwarf_exec_frame_instr( /* make_instr= */ false, + /* ret_frame_instr= */ NULL, + /* search_pc */ true, + /* search_pc_val */ pc_requested, + fde->fd_initial_location, + fde->fd_fde_instr_start, + instr_end, + table, + cie, dbg, + cfa_reg_col_num, &icount, + &dw_err); + } + if (res == DW_DLV_ERROR) { + _dwarf_error(dbg, error, dw_err); + return (res); + } else if (res == DW_DLV_NO_ENTRY) { + return res; + } + + return DW_DLV_OK; +} + +/* A consumer call for efficiently getting the register info + for all registers in one call. + + The output table rules array is size DW_REG_TABLE_SIZE. + The frame info rules array in fde_table is of size + DW_REG_TABLE_SIZE too. + + This interface really only works well with MIPS/IRIX + where DW_FRAME_CFA_COL is zero (in that case it's safe). + + It is also restricted to the case where + DW_REG_TABLE_SIZE == DW_FRAME_LAST_REG_NUM == + dbg->de_frame_reg_rules_entry_count (true for MIPS/IRIX). + If this condition is not met calling this routine can result in + incorrect output or in memory corruption. + +*/ +int +dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde, + Dwarf_Addr pc_requested, + Dwarf_Regtable * reg_table, + Dwarf_Addr * row_pc, + Dwarf_Error * error) +{ + + /* Table size: DW_REG_TABLE_SIZE */ + struct Dwarf_Frame_s fde_table; + Dwarf_Sword i = 0; + struct Dwarf_Reg_Rule_s *rule = NULL; + struct Dwarf_Regtable_Entry_s *out_rule = NULL; + int res = 0; + Dwarf_Debug dbg = 0; + + /* For this interface the size is fixed at compile time. */ + int output_table_real_data_size = DW_REG_TABLE_SIZE; + + FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); + + res = dwarf_initialize_fde_table(dbg, &fde_table, + output_table_real_data_size, + error); + if (res != DW_DLV_OK) + return res; + + + + /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks + */ + res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, + &fde_table, + DW_FRAME_CFA_COL, error); + if (res != DW_DLV_OK) { + dwarf_free_fde_table(&fde_table); + return res; + } + + out_rule = ®_table->rules[0]; + rule = &fde_table.fr_reg[0]; + for (i = 0; i < output_table_real_data_size; + i++, ++out_rule, ++rule) { + out_rule->dw_offset_relevant = rule->ru_is_off; + out_rule->dw_value_type = rule->ru_value_type; + out_rule->dw_regnum = rule->ru_register; + out_rule->dw_offset = rule->ru_offset_or_block_len; + } + for (; i < DW_REG_TABLE_SIZE; ++i, ++out_rule) { + out_rule->dw_offset_relevant = 0; + out_rule->dw_value_type = DW_EXPR_OFFSET; + out_rule->dw_regnum = DW_FRAME_UNDEFINED_VAL; + out_rule->dw_offset = 0; + } + + /* The test is just in case it's not inside the table. For non-MIPS + it could be outside the table and that is just fine, it was + really a mistake to put it in the table in 1993. */ + /* CONSTCOND */ + if (DW_FRAME_CFA_COL < DW_REG_TABLE_SIZE) { + out_rule = ®_table->rules[DW_FRAME_CFA_COL]; + out_rule->dw_offset_relevant = fde_table.fr_cfa_rule.ru_is_off; + out_rule->dw_value_type = fde_table.fr_cfa_rule.ru_value_type; + out_rule->dw_regnum = fde_table.fr_cfa_rule.ru_register; + out_rule->dw_offset = + fde_table.fr_cfa_rule.ru_offset_or_block_len; + } + + if (row_pc != NULL) + *row_pc = fde_table.fr_loc; + dwarf_free_fde_table(&fde_table); + return DW_DLV_OK; +} + +/* A consumer call for efficiently getting the register info + for all registers in one call. + + The output table rules array is size output_table_real_data_size. + (normally DW_REG_TABLE_SIZE). + The frame info rules array in fde_table is normally of size + DW_FRAME_LAST_REG_NUM. +*/ +int +dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde, + Dwarf_Addr pc_requested, + Dwarf_Regtable3 * reg_table, + Dwarf_Addr * row_pc, + Dwarf_Error * error) +{ + + struct Dwarf_Frame_s fde_table; + Dwarf_Sword i = 0; + int res = 0; + struct Dwarf_Reg_Rule_s *rule = NULL; + struct Dwarf_Regtable_Entry3_s *out_rule = NULL; + Dwarf_Debug dbg = 0; + int output_table_real_data_size = reg_table->rt3_reg_table_size; + + FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); + + output_table_real_data_size = + MIN(output_table_real_data_size, + dbg->de_frame_reg_rules_entry_count); + + res = dwarf_initialize_fde_table(dbg, &fde_table, + output_table_real_data_size, + error); + + /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks + */ + res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, + &fde_table, + DW_FRAME_CFA_COL3, error); + if (res != DW_DLV_OK) { + dwarf_free_fde_table(&fde_table); + return res; + } + + out_rule = ®_table->rt3_rules[0]; + rule = &fde_table.fr_reg[0]; + for (i = 0; i < output_table_real_data_size; + i++, ++out_rule, ++rule) { + out_rule->dw_offset_relevant = rule->ru_is_off; + out_rule->dw_value_type = rule->ru_value_type; + out_rule->dw_regnum = rule->ru_register; + out_rule->dw_offset_or_block_len = rule->ru_offset_or_block_len; + out_rule->dw_block_ptr = rule->ru_block; + } + for (; i < reg_table->rt3_reg_table_size; i++, ++out_rule) { + out_rule->dw_offset_relevant = 0; + out_rule->dw_value_type = DW_EXPR_OFFSET; + out_rule->dw_regnum = DW_FRAME_UNDEFINED_VAL; + out_rule->dw_offset_or_block_len = 0; + out_rule->dw_block_ptr = 0; + } + reg_table->rt3_cfa_rule.dw_offset_relevant = + fde_table.fr_cfa_rule.ru_is_off; + reg_table->rt3_cfa_rule.dw_value_type = + fde_table.fr_cfa_rule.ru_value_type; + reg_table->rt3_cfa_rule.dw_regnum = + fde_table.fr_cfa_rule.ru_register; + reg_table->rt3_cfa_rule.dw_offset_or_block_len = + fde_table.fr_cfa_rule.ru_offset_or_block_len; + reg_table->rt3_cfa_rule.dw_block_ptr = + fde_table.fr_cfa_rule.ru_block; + + if (row_pc != NULL) + *row_pc = fde_table.fr_loc; + + dwarf_free_fde_table(&fde_table); + return DW_DLV_OK; +} + + +/* Gets the register info for a single register at a given PC value + for the FDE specified. + +*/ +int +dwarf_get_fde_info_for_reg(Dwarf_Fde fde, + Dwarf_Half table_column, + Dwarf_Addr pc_requested, + Dwarf_Signed * offset_relevant, + Dwarf_Signed * register_num, + Dwarf_Signed * offset, + Dwarf_Addr * row_pc, Dwarf_Error * error) +{ + struct Dwarf_Frame_s fde_table; + int res; + Dwarf_Debug dbg = 0; + int output_table_real_data_size = 0; + + FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); + output_table_real_data_size = dbg->de_frame_reg_rules_entry_count; + + res = dwarf_initialize_fde_table(dbg, &fde_table, + output_table_real_data_size, + error); + if (res != DW_DLV_OK) + return res; + + + if (table_column >= output_table_real_data_size) { + dwarf_free_fde_table(&fde_table); + _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD); + return (DW_DLV_ERROR); + } + + /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks + */ + res = + _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table, + DW_FRAME_CFA_COL, error); + if (res != DW_DLV_OK) { + dwarf_free_fde_table(&fde_table); + return res; + } + + if (fde_table.fr_reg[table_column].ru_value_type != DW_EXPR_OFFSET) { + dwarf_free_fde_table(&fde_table); + _dwarf_error(NULL, error, + DW_DLE_FRAME_REGISTER_UNREPRESENTABLE); + return (DW_DLV_ERROR); + } + + if (register_num != NULL) + *register_num = fde_table.fr_reg[table_column].ru_register; + if (offset != NULL) + *offset = fde_table.fr_reg[table_column].ru_offset_or_block_len; + if (row_pc != NULL) + *row_pc = fde_table.fr_loc; + + *offset_relevant = (fde_table.fr_reg[table_column].ru_is_off); + dwarf_free_fde_table(&fde_table); + return DW_DLV_OK; +} + +/* In this interface, table_column of DW_FRAME_CFA_COL + is not meaningful. + Use dwarf_get_fde_info_for_cfa_reg3() to get the CFA. +*/ +int +dwarf_get_fde_info_for_reg3(Dwarf_Fde fde, + Dwarf_Half table_column, + Dwarf_Addr pc_requested, + Dwarf_Small * value_type, + Dwarf_Signed * offset_relevant, + Dwarf_Signed * register_num, + Dwarf_Signed * offset_or_block_len, + Dwarf_Ptr * block_ptr, + Dwarf_Addr * row_pc_out, + Dwarf_Error * error) +{ + struct Dwarf_Frame_s fde_table; + int res = 0; + + Dwarf_Debug dbg = 0; + int table_real_data_size = 0; + + FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); + table_real_data_size = dbg->de_frame_reg_rules_entry_count; + res = dwarf_initialize_fde_table(dbg, &fde_table, + table_real_data_size, error); + if (res != DW_DLV_OK) + return res; + if (table_column >= table_real_data_size) { + dwarf_free_fde_table(&fde_table); + _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD); + return (DW_DLV_ERROR); + } + + /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks + */ + res = + _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table, + DW_FRAME_CFA_COL3, error); + if (res != DW_DLV_OK) { + dwarf_free_fde_table(&fde_table); + return res; + } + + if (register_num != NULL) + *register_num = fde_table.fr_reg[table_column].ru_register; + if (offset_or_block_len != NULL) + *offset_or_block_len = + fde_table.fr_reg[table_column].ru_offset_or_block_len; + if (row_pc_out != NULL) + *row_pc_out = fde_table.fr_loc; + if (block_ptr) + *block_ptr = fde_table.fr_reg[table_column].ru_block; + + /* Without value_type the data cannot be understood, so we insist + on it being present, we don't test it. */ + *value_type = fde_table.fr_reg[table_column].ru_value_type; + *offset_relevant = (fde_table.fr_reg[table_column].ru_is_off); + dwarf_free_fde_table(&fde_table); + return DW_DLV_OK; + +} + +/* For latest DWARF, this is the preferred interface. + It more portably deals with the CFA by not + making the CFA a column number, which means + DW_FRAME_CFA_COL becomes an index like DW_CFA_SAME_VALUE, + a special value, not something one uses as an index. */ +int +dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde, + Dwarf_Addr pc_requested, + Dwarf_Small * value_type, + Dwarf_Signed * offset_relevant, + Dwarf_Signed * register_num, + Dwarf_Signed * offset_or_block_len, + Dwarf_Ptr * block_ptr, + Dwarf_Addr * row_pc_out, + Dwarf_Error * error) +{ + struct Dwarf_Frame_s fde_table; + int res; + Dwarf_Debug dbg = 0; + + int table_real_data_size = 0; + + FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); + + table_real_data_size = dbg->de_frame_reg_rules_entry_count; + res = dwarf_initialize_fde_table(dbg, &fde_table, + table_real_data_size, error); + if (res != DW_DLV_OK) + return res; + res = + _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table, + DW_FRAME_CFA_COL3, error); + if (res != DW_DLV_OK) { + dwarf_free_fde_table(&fde_table); + return res; + } + + if (register_num != NULL) + *register_num = fde_table.fr_cfa_rule.ru_register; + if (offset_or_block_len != NULL) + *offset_or_block_len = + fde_table.fr_cfa_rule.ru_offset_or_block_len; + if (row_pc_out != NULL) + *row_pc_out = fde_table.fr_loc; + if (block_ptr) + *block_ptr = fde_table.fr_cfa_rule.ru_block; + + /* Without value_type the data cannot be understood, so we insist + on it being present, we don't test it. */ + *value_type = fde_table.fr_cfa_rule.ru_value_type; + *offset_relevant = fde_table.fr_cfa_rule.ru_is_off; + dwarf_free_fde_table(&fde_table); + return DW_DLV_OK; +} + + + +/* + Return pointer to the instructions in the dwarf + fde. +*/ +int +dwarf_get_fde_instr_bytes(Dwarf_Fde inFde, Dwarf_Ptr * outinstraddr, + Dwarf_Unsigned * outaddrlen, + Dwarf_Error * error) +{ + Dwarf_Unsigned len = 0; + unsigned char *instrs = 0; + Dwarf_Debug dbg = 0; + + if (inFde == NULL) { + _dwarf_error(dbg, error, DW_DLE_FDE_NULL); + return (DW_DLV_ERROR); + } + + dbg = inFde->fd_dbg; + if (dbg == NULL) { + _dwarf_error(dbg, error, DW_DLE_FDE_DBG_NULL); + return (DW_DLV_ERROR); + } + + instrs = inFde->fd_fde_instr_start; + + len = (inFde->fd_fde_start + inFde->fd_length + + inFde->fd_length_size + inFde->fd_extension_size) - instrs; + + *outinstraddr = instrs; + *outaddrlen = len; + return DW_DLV_OK; +} + +/* Allows getting an fde from its table via an index. + With more error checking than simply indexing oneself. +*/ +int +dwarf_get_fde_n(Dwarf_Fde * fde_data, + Dwarf_Unsigned fde_index, + Dwarf_Fde * returned_fde, Dwarf_Error * error) +{ + Dwarf_Debug dbg = 0; + + if (fde_data == NULL) { + _dwarf_error(dbg, error, DW_DLE_FDE_PTR_NULL); + return (DW_DLV_ERROR); + } + + FDE_NULL_CHECKS_AND_SET_DBG(*fde_data, dbg); + + if (fde_index >= dbg->de_fde_count) { + return (DW_DLV_NO_ENTRY); + } + *returned_fde = (*(fde_data + fde_index)); + return DW_DLV_OK; +} + + +/* + Lopc and hipc are extensions to the interface to + return the range of addresses that are described + by the returned fde. +*/ +int +dwarf_get_fde_at_pc(Dwarf_Fde * fde_data, + Dwarf_Addr pc_of_interest, + Dwarf_Fde * returned_fde, + Dwarf_Addr * lopc, + Dwarf_Addr * hipc, Dwarf_Error * error) +{ + Dwarf_Debug dbg = NULL; + Dwarf_Fde fde = NULL; + Dwarf_Fde entryfde = NULL; + + if (fde_data == NULL) { + _dwarf_error(NULL, error, DW_DLE_FDE_PTR_NULL); + return (DW_DLV_ERROR); + } + + /* Assumes fde_data table has at least one entry. */ + entryfde = *fde_data; + FDE_NULL_CHECKS_AND_SET_DBG(entryfde, dbg); + + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); + return (DW_DLV_ERROR); + } + { + /* The fde's are sorted by their addresses. Binary search to + find correct fde. */ + Dwarf_Signed low = 0; + Dwarf_Signed high = dbg->de_fde_count - 1L; + Dwarf_Signed middle = 0; + Dwarf_Fde cur_fde; + + while (low <= high) { + middle = (low + high) / 2; + cur_fde = fde_data[middle]; + if (pc_of_interest < cur_fde->fd_initial_location) { + high = middle - 1; + } else if (pc_of_interest >= + (cur_fde->fd_initial_location + + cur_fde->fd_address_range)) { + low = middle + 1; + } else { + fde = fde_data[middle]; + break; + } + } + } + + if (fde) { + if (lopc != NULL) + *lopc = fde->fd_initial_location; + if (hipc != NULL) + *hipc = + fde->fd_initial_location + fde->fd_address_range - 1; + *returned_fde = fde; + return (DW_DLV_OK); + } + + return (DW_DLV_NO_ENTRY); +} + + +/* Expands a single frame instruction block + into a n array of Dwarf_Frame_Op-s. +*/ +int +dwarf_expand_frame_instructions(Dwarf_Debug dbg, + Dwarf_Ptr instruction, + Dwarf_Unsigned i_length, + Dwarf_Frame_Op ** returned_op_list, + Dwarf_Signed * returned_op_count, + Dwarf_Error * error) +{ + Dwarf_Sword instr_count; + int res; + int dw_err; + + if (dbg == 0) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + + if (returned_op_list == 0 || returned_op_count == 0) { + _dwarf_error(dbg, error, DW_DLE_RET_OP_LIST_NULL); + return (DW_DLV_ERROR); + } + + /* The cast to Dwarf_Ptr may get a compiler warning, but it is safe + as it is just an i_length offset from 'instruction' itself. A + caller has made a big mistake if the result is not a valid + pointer. */ + res = _dwarf_exec_frame_instr( /* make_instr= */ true, + returned_op_list, + /* search_pc */ false, + /* search_pc_val */ 0, + /* location */ 0, + instruction, + (Dwarf_Ptr) ((Dwarf_Unsigned) + instruction + i_length), + /* Dwarf_Frame */ NULL, + /* cie_ptr */ NULL, + dbg, + DW_FRAME_CFA_COL, &instr_count, + &dw_err); + if (res != DW_DLV_OK) { + if (res == DW_DLV_ERROR) { + _dwarf_error(dbg, error, dw_err); + } + return (res); + } + + *returned_op_count = instr_count; + return DW_DLV_OK; +} + + +/* Used by dwarfdump -v to print offsets, for debugging + dwarf info. + The dwarf_ version is preferred over the obsolete _dwarf version. + _dwarf version kept for compatibility. +*/ +/* ARGSUSED 4 */ +int +_dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde, + Dwarf_Off * fde_off, Dwarf_Off * cie_off, + Dwarf_Error * err) +{ + return _dwarf_fde_section_offset(dbg,in_fde,fde_off, + cie_off,err); +} +/* ARGSUSED 4 */ +int +dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde, + Dwarf_Off * fde_off, Dwarf_Off * cie_off, + Dwarf_Error * err) +{ + char *start = 0; + char *loc = 0; + + + + start = (char *) in_fde->fd_section_ptr; + loc = (char *) in_fde->fd_fde_start; + + *fde_off = (loc - start); + *cie_off = in_fde->fd_cie_offset; + return DW_DLV_OK; +} + +/* Used by dwarfdump -v to print offsets, for debugging + dwarf info. + The dwarf_ version is preferred over the obsolete _dwarf version. + _dwarf version kept for compatibility. +*/ +/* ARGSUSED 4 */ +int +_dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie, + Dwarf_Off * cie_off, Dwarf_Error * err) +{ + return dwarf_cie_section_offset(dbg,in_cie,cie_off,err); +} +/* ARGSUSED 4 */ +int +dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie, + Dwarf_Off * cie_off, Dwarf_Error * err) +{ + char *start = 0; + char *loc = 0; + + start = (char *) in_cie->ci_section_ptr; + loc = (char *) in_cie->ci_cie_start; + + *cie_off = (loc - start); + return DW_DLV_OK; +} + +/* Returns a pointer to target-specific augmentation data thru augdata + and returns the length of the data thru augdata_len. + + It's up to the consumer code to know how to interpret the bytes + of target-specific data (endian issues apply too, these + are just raw bytes pointed to). + See Linux Standard Base Core Specification version 3.0 for + the details on .eh_frame info. + + Returns DW_DLV_ERROR if fde is NULL or some other serious + error. + Returns DW_DLV_NO_ENTRY if there is no target-specific + augmentation data. + + The bytes pointed to are in the Dwarf_Cie, and as long as that + is valid the bytes are there. No 'dealloc' call is needed + for the bytes. +*/ +int +dwarf_get_cie_augmentation_data(Dwarf_Cie cie, + Dwarf_Small ** augdata, + Dwarf_Unsigned * augdata_len, + Dwarf_Error * error) +{ + if (cie == NULL) { + _dwarf_error(NULL, error, DW_DLE_CIE_NULL); + return (DW_DLV_ERROR); + } + if (cie->ci_gnu_eh_augmentation_len == 0) { + return DW_DLV_NO_ENTRY; + } + *augdata = (Dwarf_Small *) (cie->ci_gnu_eh_augmentation_bytes); + *augdata_len = cie->ci_gnu_eh_augmentation_len; + return DW_DLV_OK; +} + + +/* Returns a pointer to target-specific augmentation data thru augdata + and returns the length of the data thru augdata_len. + + It's up to the consumer code to know how to interpret the bytes + of target-specific data (endian issues apply too, these + are just raw bytes pointed to). + See Linux Standard Base Core Specification version 3.0 for + the details on .eh_frame info. + + Returns DW_DLV_ERROR if fde is NULL or some other serious + error. + Returns DW_DLV_NO_ENTRY if there is no target-specific + augmentation data. + + The bytes pointed to are in the Dwarf_Fde, and as long as that + is valid the bytes are there. No 'dealloc' call is needed + for the bytes. + +*/ +int +dwarf_get_fde_augmentation_data(Dwarf_Fde fde, + Dwarf_Small * *augdata, + Dwarf_Unsigned * augdata_len, + Dwarf_Error * error) +{ + Dwarf_Cie cie = 0; + + if (fde == NULL) { + _dwarf_error(NULL, error, DW_DLE_FDE_NULL); + return (DW_DLV_ERROR); + } + cie = fde->fd_cie; + if (cie == NULL) { + _dwarf_error(NULL, error, DW_DLE_CIE_NULL); + return (DW_DLV_ERROR); + } + if (cie->ci_gnu_eh_augmentation_len == 0) { + return DW_DLV_NO_ENTRY; + } + *augdata = (Dwarf_Small *) fde->fd_gnu_eh_augmentation_bytes; + *augdata_len = fde->fd_gnu_eh_augmentation_len; + return DW_DLV_OK; +} + + +/* Initialize with same_value , a value which makes sense + for IRIX/MIPS. + The correct value to use is ABI dependent. + For register-windows machines most + or all registers should get DW_FRAME_UNDEFINED_VAL as the + correct initial value. + Some think DW_FRAME_UNDEFINED_VAL is always the + right value. + + For some ABIs a setting which varies by register + would be more appropriate. + + FIXME. */ + +static void +_dwarf_init_regrule_table(struct Dwarf_Reg_Rule_s *t1reg, + int last_reg_num, int initial_value) +{ + struct Dwarf_Reg_Rule_s *t1end = t1reg + last_reg_num; + + for (; t1reg < t1end; t1reg++) { + t1reg->ru_is_off = 0; + t1reg->ru_value_type = DW_EXPR_OFFSET; + t1reg->ru_register = initial_value; + t1reg->ru_offset_or_block_len = 0; + t1reg->ru_block = 0; + } +} + +#if 0 +/* Used solely for debugging libdwarf. */ +static void +dump_frame_rule(char *msg, struct Dwarf_Reg_Rule_s *reg_rule) +{ + printf + ("%s type %s (0x%x), is_off %d reg %d offset 0x%llx blockp 0x%llx \n", + msg, + (reg_rule->ru_value_type == + DW_EXPR_OFFSET) ? "DW_EXPR_OFFSET" : (reg_rule-> + ru_value_type == + DW_EXPR_VAL_OFFSET) ? + "DW_EXPR_VAL_OFFSET" : (reg_rule->ru_value_type == + DW_EXPR_VAL_EXPRESSION) ? + "DW_EXPR_VAL_EXPRESSION" : (reg_rule->ru_value_type == + DW_EXPR_EXPRESSION) ? + "DW_EXPR_EXPRESSION" : "Unknown", + (unsigned) reg_rule->ru_value_type, (int) reg_rule->ru_is_off, + (int) reg_rule->ru_register, + (unsigned long long) reg_rule->ru_offset_or_block_len, + (unsigned long long) reg_rule->ru_block); + return; +} +#endif + +/* This allows consumers to set the 'initial value' so that + an ISA/ABI specific default can be used, dynamically, + at run time. Useful for dwarfdump and non-MIPS architectures.. + The value defaults to one of + DW_FRAME_SAME_VALUE or DW_FRAME_UNKNOWN_VALUE + but dwarfdump can dump multiple ISA/ABI objects so + we may want to get this set to what the ABI says is correct. + + Returns the value that was present before we changed it here. +*/ + +Dwarf_Half +dwarf_set_frame_rule_inital_value(Dwarf_Debug dbg, Dwarf_Half value) +{ + Dwarf_Half orig = dbg->de_frame_rule_initial_value; + + dbg->de_frame_rule_initial_value = value; + return orig; +} + +/* This allows consumers to set the array size of the reg rules + table so that + an ISA/ABI specific value can be used, dynamically, + at run time. Useful for non-MIPS archtectures. + The value defaults to DW_FRAME_LAST_REG_NUM. + but dwarfdump can dump multiple ISA/ABI objects so + consumers want to get this set to what the ABI says is correct. + + Returns the value that was present before we changed it here. +*/ + +Dwarf_Half +dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value) +{ + Dwarf_Half orig = dbg->de_frame_reg_rules_entry_count; + + dbg->de_frame_reg_rules_entry_count = value; + return orig; +} + + +static int +dwarf_initialize_fde_table(Dwarf_Debug dbg, + struct Dwarf_Frame_s *fde_table, + unsigned table_real_data_size, + Dwarf_Error * error) +{ + unsigned entry_size = sizeof(struct Dwarf_Frame_s); + + fde_table->fr_loc = 0; + fde_table->fr_reg_count = table_real_data_size; + fde_table->fr_next = 0; + + fde_table->fr_reg = (struct Dwarf_Reg_Rule_s *) + calloc(entry_size, table_real_data_size); + if (fde_table->fr_reg == 0) { + _dwarf_error(dbg, error, DW_DLE_DF_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + return DW_DLV_OK; + +} +static void +dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table) +{ + free(fde_table->fr_reg); + fde_table->fr_reg_count = 0; + fde_table->fr_reg = 0; +} + + +/* Return DW_DLV_OK if we succeed. else return DW_DLV_ERROR. +*/ +int +_dwarf_frame_constructor(Dwarf_Debug dbg, void *frame) +{ + struct Dwarf_Frame_s *fp = frame; + + if (!dbg) { + return DW_DLV_ERROR; + } + + fp->fr_reg = calloc(dbg->de_frame_reg_rules_entry_count, + sizeof(struct Dwarf_Reg_Rule_s)); + if (!fp->fr_reg) { + return DW_DLV_ERROR; + } + fp->fr_reg_count = dbg->de_frame_reg_rules_entry_count; + return DW_DLV_OK; +} + +void +_dwarf_frame_destructor(void *frame) +{ + struct Dwarf_Frame_s *fp = frame; + + if (fp->fr_reg) + free(fp->fr_reg); + fp->fr_reg = 0; + fp->fr_reg_count = 0; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,400 @@ +/* + + Copyright (C) 2000, 2004, 2006 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +/* The dwarf 2.0 standard dictates that only the following + * fields can be read when an unexpected augmentation string + * (in the cie) is encountered: CIE length, CIE_id, version and + * augmentation; FDE: length, CIE pointer, initial location and + * address range. Unfortunately, with the above restrictions, it + * is impossible to read the instruction table from a CIE or a FDE + * when a new augmentation string is encountered. + * To fix this problem, the following layout is used, if the + * augmentation string starts with the string "z". + * CIE FDE + * length length + * CIE_id CIE_pointer + * version initial_location + * augmentation address_range + * length_of_augmented_fields (*NEW*) + * code_alignment_factor Any new fields as necessary + * data_alignment_factor instruction_table + * return_address + * length_of_augmented fields + * Any new fields as necessary + * initial_instructions + * + * The type of all the old data items are the same as what is + * described in dwarf 2.0 standard. The length_of_augmented_fields + * is an LEB128 data item that denotes the size (in bytes) of + * the augmented fields (not including the size of + * "length_of_augmented_fields" itself). + + * Handling of cie augmentation strings is necessarly a heuristic. + * See dwarf_frame.c for the currently known augmentation strings. + + + ---START SGI-ONLY COMMENT: + * SGI-IRIX versions of cie or fde were intended to use "z1", "z2" as the + * augmenter strings if required for new augmentation. + * However, that never happened (as of March 2005). + * + * The fde's augmented by the string "z" have a new field + * (signed constant, 4 byte field) + * called offset_into_exception_tables, following the + * length_of_augmented field. This field contains an offset + * into the "_MIPS_eh_region", which describes + * the IRIX CC exception handling tables. + ---END SGI-ONLY COMMENT + + + * GNU .eh_frame has an augmentation string of z[RLP]* (gcc 3.4) + * The similarity to IRIX 'z' (and proposed but never + * implemented IRIX z1, z2 etc) was confusing things. + * If the section is .eh_frame then 'z' means GNU exception + * information 'Augmentation Data' not IRIX 'z'. + * See The Linux Standard Base Core Specification version 3.0 + */ + +#define DW_DEBUG_FRAME_VERSION 1 /* DWARF2 */ +#define DW_DEBUG_FRAME_VERSION3 3 /* DWARF3 */ +#define DW_DEBUG_FRAME_AUGMENTER_STRING "mti v1" + +/* The value of the offset field for Cie's. */ +#define DW_CIE_OFFSET ~(0x0) + +/* The augmentation string may be NULL. */ +#define DW_EMPTY_STRING "" + +#define DW_FRAME_INSTR_OPCODE_SHIFT 6 +#define DW_FRAME_INSTR_OFFSET_MASK 0x3f + +/* + This struct denotes the rule for a register in a row of + the frame table. In other words, it is one element of + the table. +*/ +struct Dwarf_Reg_Rule_s { + + /* + Is a flag indicating whether the rule includes the offset + field, ie whether the ru_offset field is valid or not. + Applies only if DW_EXPR_OFFSET or DW_EXPR_VAL_OFFSET. + It is important, since reg+offset (offset of 0) is different from + just 'register' since the former means 'read memory at address + given by the sum of register contents plus offset to get the + value'. whereas the latter means 'the value is in the register'. + + The 'register' numbers are either real registers (ie, table + columns defined as real registers) or defined entries that are + not really hardware registers, such as DW_FRAME_SAME_VAL or + DW_FRAME_CFA_COL. + + */ + Dwarf_Sbyte ru_is_off; + + /* DW_EXPR_OFFSET (0, DWARF2) + DW_EXPR_VAL_OFFSET 1 (dwarf2/3) + DW_EXPR_EXPRESSION 2 (dwarf2/3) + DW_EXPR_VAL_EXPRESSION 3 (dwarf2/3) + See dwarf_frame.h. */ + Dwarf_Sbyte ru_value_type; + + /* Register involved in this rule. */ + Dwarf_Half ru_register; + + /* Offset to add to register, if indicated by ru_is_offset + and if DW_EXPR_OFFSET or DW_EXPR_VAL_OFFSET. + If DW_EXPR_EXPRESSION or DW_EXPR_VAL_EXPRESSION + this is DW_FORM_block block-length, not offset. */ + Dwarf_Unsigned ru_offset_or_block_len; + + /* For DW_EXPR_EXPRESSION DW_EXPR_VAL_EXPRESSION these is set, + else 0. */ + Dwarf_Small *ru_block; +}; + +typedef struct Dwarf_Frame_s *Dwarf_Frame; + +/* + This structure represents a row of the frame table. + Fr_loc is the pc value for this row, and Fr_reg + contains the rule for each column. + + Entry DW_FRAME_CFA_COL of fr_reg was the tradional MIPS + way of setting CFA. cfa_rule is the new one. +*/ +struct Dwarf_Frame_s { + + /* Pc value corresponding to this row of the frame table. */ + Dwarf_Addr fr_loc; + + /* Rules for all the registers in this row. */ + struct Dwarf_Reg_Rule_s fr_cfa_rule; + + /* fr_reg_count is the the number of + entries of the fr_reg array. */ + unsigned long fr_reg_count; + struct Dwarf_Reg_Rule_s *fr_reg; + + Dwarf_Frame fr_next; +}; + +typedef struct Dwarf_Frame_Op_List_s *Dwarf_Frame_Op_List; + +/* This is used to chain together Dwarf_Frame_Op structures. */ +struct Dwarf_Frame_Op_List_s { + Dwarf_Frame_Op *fl_frame_instr; + Dwarf_Frame_Op_List fl_next; +}; + +/* See dwarf_frame.c for the heuristics used to set the + Dwarf_Cie ci_augmentation_type. + + This succinctly helps interpret the size and meaning of .debug_frame + and (for gcc) .eh_frame. + + In the case of gcc .eh_frame (gcc 3.3, 3.4) + z may be followed by one or more of + L R P. + +*/ +enum Dwarf_augmentation_type { + aug_empty_string, /* Default empty augmentation string. */ + aug_irix_exception_table, /* IRIX plain "z", + for exception handling, IRIX CC compiler. + Proposed z1 z2 ... never implemented. */ + aug_gcc_eh_z, /* gcc z augmentation, (including + L R P variations). gcc 3.3 3.4 exception + handling in eh_frame. */ + aug_irix_mti_v1, /* IRIX "mti v1" augmentation string. Probably + never in any released SGI-IRIX compiler. */ + aug_eh, /* For gcc .eh_frame, "eh" is the string., + gcc 1,2, egcs. Older values. */ + aug_unknown, /* Unknown augmentation, we cannot do much. */ + aug_past_last +}; + + +/* + This structure contains all the pertinent info for a Cie. Most + of the fields are taken straight from the definition of a Cie. + Ci_cie_start points to the address (in .debug_frame) where this + Cie begins. Ci_cie_instr_start points to the first byte of the + frame instructions for this Cie. Ci_dbg points to the associated + Dwarf_Debug structure. Ci_initial_table is a pointer to the table + row generated by the instructions for this Cie. +*/ +struct Dwarf_Cie_s { + Dwarf_Word ci_length; + char *ci_augmentation; + Dwarf_Small ci_code_alignment_factor; + Dwarf_Sbyte ci_data_alignment_factor; + Dwarf_Small ci_return_address_register; + Dwarf_Small *ci_cie_start; + Dwarf_Small *ci_cie_instr_start; + Dwarf_Debug ci_dbg; + Dwarf_Frame ci_initial_table; + Dwarf_Cie ci_next; + Dwarf_Small ci_length_size; + Dwarf_Small ci_extension_size; + Dwarf_Half ci_cie_version_number; + enum Dwarf_augmentation_type ci_augmentation_type; + + /* The following 2 for GNU .eh_frame exception handling + Augmentation Data. Set if ci_augmentation_type + is aug_gcc_eh_z. Zero if unused. */ + Dwarf_Unsigned ci_gnu_eh_augmentation_len; + Dwarf_Ptr ci_gnu_eh_augmentation_bytes; + + /* These are extracted from the gnu eh_frame + augmentation if the + augmentation begins with 'z'. See Linux LSB documents. + Otherwize these are zero. */ + unsigned char ci_gnu_personality_handler_encoding; + unsigned char ci_gnu_lsda_encoding; + unsigned char ci_gnu_fde_begin_encoding; + + /* If 'P' augmentation present, is handler addr. Else + is zero. */ + Dwarf_Addr ci_gnu_personality_handler_addr; + + + /* In creating list of cie's (which will become an array) + record the position so fde can get it on fde creation. */ + Dwarf_Unsigned ci_index; + Dwarf_Small * ci_section_ptr; +}; + +/* + This structure contains all the pertinent info for a Fde. + Most of the fields are taken straight from the definition. + fd_cie_index is the index of the Cie associated with this + Fde in the list of Cie's for this debug_frame. Fd_cie + points to the corresponsing Dwarf_Cie structure. Fd_fde_start + points to the start address of the Fde. Fd_fde_instr_start + points to the start of the instructions for this Fde. Fd_dbg + points to the associated Dwarf_Debug structure. +*/ +struct Dwarf_Fde_s { + Dwarf_Unsigned fd_length; + Dwarf_Addr fd_cie_offset; + Dwarf_Unsigned fd_cie_index; + Dwarf_Cie fd_cie; + Dwarf_Addr fd_initial_location; + Dwarf_Small *fd_initial_loc_pos; + Dwarf_Addr fd_address_range; + Dwarf_Small *fd_fde_start; + Dwarf_Small *fd_fde_instr_start; + Dwarf_Debug fd_dbg; + + /* fd_offset_into_exception_tables is SGI/IRIX exception table + offset. Unused and zero if not IRIX .debug_frame. */ + Dwarf_Signed fd_offset_into_exception_tables; + + Dwarf_Fde fd_next; + Dwarf_Small fd_length_size; + Dwarf_Small fd_extension_size; + /* The following 2 for GNU .eh_frame exception handling + Augmentation Data. Set if CIE ci_augmentation_type + is aug_gcc_eh_z. Zero if unused. */ + Dwarf_Unsigned fd_gnu_eh_augmentation_len; + Dwarf_Ptr fd_gnu_eh_augmentation_bytes; + Dwarf_Addr fd_gnu_eh_lsda; /* If 'L' augmentation letter + present: is address of the + Language Specific Data Area (LSDA). If not 'L" is zero. */ + + /* The following 3 are about the Elf section the FDEs come from. */ + Dwarf_Small * fd_section_ptr; + Dwarf_Unsigned fd_section_length; + Dwarf_Unsigned fd_section_index; + +}; + + +int + _dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist, + Dwarf_Off ** offsetlist, + Dwarf_Signed * returncount, + Dwarf_Error * err); + +int +_dwarf_get_fde_list_internal(Dwarf_Debug dbg, + Dwarf_Cie ** cie_data, + Dwarf_Signed * cie_element_count, + Dwarf_Fde ** fde_data, + Dwarf_Signed * fde_element_count, + Dwarf_Small * section_ptr, + Dwarf_Unsigned section_index, + Dwarf_Unsigned section_length, + Dwarf_Unsigned cie_id_value, + int use_gnu_cie_calc, /* If non-zero, + this is gcc eh_frame. */ + Dwarf_Error * error); + +enum Dwarf_augmentation_type +_dwarf_get_augmentation_type(Dwarf_Debug dbg, + Dwarf_Small *augmentation_string, + int is_gcc_eh_frame); + +Dwarf_Unsigned _dwarf_get_return_address_reg(Dwarf_Small *frame_ptr, + int version, + unsigned long *size); + +/* Temporary recording of crucial cie/fde prefix data. + * Vastly simplifies some argument lists. + */ +struct cie_fde_prefix_s { + Dwarf_Small * cf_start_addr; + Dwarf_Small * cf_addr_after_prefix; + Dwarf_Unsigned cf_length; + int cf_local_length_size; + int cf_local_extension_size; + Dwarf_Unsigned cf_cie_id; + Dwarf_Small * cf_cie_id_addr; /* used for eh_frame calculations. */ + + /* Simplifies passing around these values to create fde having + these here. */ + Dwarf_Small * cf_section_ptr; + Dwarf_Unsigned cf_section_index; + Dwarf_Unsigned cf_section_length; +}; + +int +_dwarf_exec_frame_instr(Dwarf_Bool make_instr, + Dwarf_Frame_Op ** ret_frame_instr, + Dwarf_Bool search_pc, + Dwarf_Addr search_pc_val, + Dwarf_Addr initial_loc, + Dwarf_Small * start_instr_ptr, + Dwarf_Small * final_instr_ptr, + Dwarf_Frame table, + Dwarf_Cie cie, + Dwarf_Debug dbg, + Dwarf_Half reg_num_of_cfa, + Dwarf_Sword * returned_count, + int *returned_error); + + +int dwarf_read_cie_fde_prefix(Dwarf_Debug dbg, + Dwarf_Small *frame_ptr_in, + Dwarf_Small *section_ptr_in, + Dwarf_Unsigned section_index_in, + Dwarf_Unsigned section_length_in, + struct cie_fde_prefix_s *prefix_out, + Dwarf_Error *error); + +int dwarf_create_fde_from_after_start(Dwarf_Debug dbg, + struct cie_fde_prefix_s * prefix, + Dwarf_Small *section_pointer, + Dwarf_Small *frame_ptr, + int use_gnu_cie_calc, + Dwarf_Cie cie_ptr_in, + Dwarf_Fde *fde_ptr_out, + Dwarf_Error *error); + +int dwarf_create_cie_from_after_start(Dwarf_Debug dbg, + struct cie_fde_prefix_s *prefix, + Dwarf_Small* section_pointer, + Dwarf_Small* frame_ptr, + Dwarf_Unsigned cie_count, + int use_gnu_cie_calc, + Dwarf_Cie *cie_ptr_out, + Dwarf_Error *error); + + +int _dwarf_frame_constructor(Dwarf_Debug dbg,void * ); +void _dwarf_frame_destructor (void *); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame2.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame2.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1447 @@ +/* + + Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + +/* + This implements _dwarf_get_fde_list_internal() + and related helper functions for reading cie/fde data. +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include +#include "dwarf_frame.h" +#include "dwarf_arange.h" /* using Arange as a way to build a + list */ + + +static int dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr, + Dwarf_Cie cur_cie_ptr, + Dwarf_Cie * cie_ptr_to_use_out, + Dwarf_Cie head_cie_ptr); +static void dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr, + Dwarf_Cie head_cie_ptr); +static int dwarf_create_cie_from_start(Dwarf_Debug dbg, + Dwarf_Small * cie_ptr_val, + Dwarf_Small * section_ptr, + Dwarf_Unsigned section_index, + Dwarf_Unsigned section_length, + Dwarf_Small * frame_ptr_end, + Dwarf_Unsigned cie_id_value, + Dwarf_Unsigned cie_count, + int use_gnu_cie_calc, + Dwarf_Cie * cie_ptr_to_use_out, + Dwarf_Error * error); + +static Dwarf_Small *get_cieptr_given_offset(Dwarf_Unsigned cie_id_value, + int use_gnu_cie_calc, + Dwarf_Small * section_ptr, + Dwarf_Small * cie_id_addr); +static int get_gcc_eh_augmentation(Dwarf_Debug dbg, + Dwarf_Small * frame_ptr, + unsigned long + *size_of_augmentation_data, + enum Dwarf_augmentation_type augtype, + Dwarf_Small * section_pointer, + Dwarf_Small * fde_eh_encoding_out, + char *augmentation); + +static int + gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation, + Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len, + unsigned char *pers_hand_enc_out, + unsigned char *lsda_enc_out, + unsigned char *fde_begin_enc_out, + Dwarf_Addr * gnu_pers_addr_out); + + +static int read_encoded_ptr(Dwarf_Debug dbg, + Dwarf_Small * section_pointer, + Dwarf_Small * input_field, + int gnu_encoding, + Dwarf_Unsigned * addr, + Dwarf_Small ** input_field_out); + + + +static int qsort_compare(const void *elem1, const void *elem2); + + +/* Adds 'newone' to the end of the list starting at 'head' + and makes the new one 'cur'rent. */ +static void +chain_up_fde(Dwarf_Fde newone, Dwarf_Fde * head, Dwarf_Fde * cur) +{ + if (*head == NULL) + *head = newone; + else { + (*cur)->fd_next = newone; + } + *cur = newone; + +} + +/* Adds 'newone' to the end of the list starting at 'head' + and makes the new one 'cur'rent. */ +static void +chain_up_cie(Dwarf_Cie newone, Dwarf_Cie * head, Dwarf_Cie * cur) +{ + if (*head == NULL) { + *head = newone; + } else { + (*cur)->ci_next = newone; + } + *cur = newone; +} + +#if 0 +/* For debugging only. */ +static void +print_prefix(struct cie_fde_prefix_s *prefix, int line) +{ + printf("prefix-print, prefix at 0x%lx, line %d\n", + (long) prefix, line); + printf(" start addr 0x%lx after prefix 0x%lx\n", + (long) prefix->cf_start_addr, + (long) prefix->cf_addr_after_prefix); + printf(" length 0x%llx, len size %d ext size %d\n", (long long) + (unsigned long long) prefix->cf_length, + prefix->cf_local_length_size, + prefix->cf_local_extension_size); + printf(" cie_id 0x%llx cie_id cie_id_addr 0x%lx\n", + (unsigned long long) prefix->cf_cie_id, + (long) prefix->cf_cie_id_addr); + printf + (" sec ptr 0x%lx sec index %lld sec len 0x%llx sec past end 0x%lx\n", + (long) prefix->cf_section_ptr, + (long long) prefix->cf_section_index, + (unsigned long long) prefix->cf_section_length, + (long) prefix->cf_section_ptr + prefix->cf_section_length); +} +#endif + + + +/* Internal function called from various places to create + lists of CIEs and FDEs. Not directly called + by consumer code */ +int +_dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, + Dwarf_Signed * cie_element_count, + Dwarf_Fde ** fde_data, + Dwarf_Signed * fde_element_count, + Dwarf_Small * section_ptr, + Dwarf_Unsigned section_index, + Dwarf_Unsigned section_length, + Dwarf_Unsigned cie_id_value, + int use_gnu_cie_calc, Dwarf_Error * error) +{ + /* Scans the debug_frame section. */ + Dwarf_Small *frame_ptr = section_ptr; + Dwarf_Small *frame_ptr_end = section_ptr + section_length; + + + + /* + New_cie points to the Cie being read, and head_cie_ptr and + cur_cie_ptr are used for chaining them up in sequence. + In case cie's are reused aggressively we need tail_cie_ptr + to add to the chain. If we re-use an early cie + later on, that does not mean we chain a new cie to the early one, + we always chain it to the tail. */ + Dwarf_Cie head_cie_ptr = NULL; + Dwarf_Cie cur_cie_ptr = NULL; + Dwarf_Cie tail_cie_ptr = NULL; + Dwarf_Word cie_count = 0; + + /* + Points to a list of contiguous pointers to Dwarf_Cie structures. + */ + Dwarf_Cie *cie_list_ptr = 0; + + + /* + New_fde points to the Fde being created, and head_fde_ptr and + cur_fde_ptr are used to chain them up. */ + Dwarf_Fde head_fde_ptr = NULL; + Dwarf_Fde cur_fde_ptr = NULL; + Dwarf_Word fde_count = 0; + + /* + Points to a list of contiguous pointers to Dwarf_Fde structures. + */ + Dwarf_Fde *fde_list_ptr = NULL; + + Dwarf_Word i = 0; + int res = 0; + + if (frame_ptr == 0) { + return DW_DLV_NO_ENTRY; + } + + /* We create the fde and cie arrays. Processing each CIE as we come + to it or as an FDE refers to it. We cannot process 'late' CIEs + late as GNU .eh_frame complexities mean we need the whole CIE + before we can process the FDE correctly. */ + while (frame_ptr < frame_ptr_end) { + + struct cie_fde_prefix_s prefix; + + /* First read in the 'common prefix' to figure out what we are + to do with this entry. */ + memset(&prefix, 0, sizeof(prefix)); + res = dwarf_read_cie_fde_prefix(dbg, + frame_ptr, section_ptr, + section_index, + section_length, &prefix, error); + if (res == DW_DLV_ERROR) { + dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); + return res; + } + if (res == DW_DLV_NO_ENTRY) + break; + frame_ptr = prefix.cf_addr_after_prefix; + if (frame_ptr >= frame_ptr_end) { + dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); + _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); + return DW_DLV_ERROR; + + } + + if (prefix.cf_cie_id == cie_id_value) { + /* This is a CIE. */ + Dwarf_Cie cie_ptr_to_use = 0; + + int res = dwarf_find_existing_cie_ptr(prefix.cf_start_addr, + cur_cie_ptr, + &cie_ptr_to_use, + head_cie_ptr); + + if (res == DW_DLV_OK) { + cur_cie_ptr = cie_ptr_to_use; + /* Ok. Seen already. */ + } else if (res == DW_DLV_NO_ENTRY) { + /* CIE before its FDE in this case. */ + res = dwarf_create_cie_from_after_start(dbg, + &prefix, + section_ptr, + frame_ptr, + cie_count, + use_gnu_cie_calc, + &cie_ptr_to_use, + error); + /* ASSERT: res==DW_DLV_NO_ENTRY impossible. */ + if (res == DW_DLV_ERROR) { + dealloc_fde_cie_list_internal(head_fde_ptr, + head_cie_ptr); + return res; + } + /* ASSERT res != DW_DLV_NO_ENTRY */ + cie_count++; + chain_up_cie(cie_ptr_to_use, &head_cie_ptr, + &tail_cie_ptr); + cur_cie_ptr = tail_cie_ptr; + } else { /* res == DW_DLV_ERROR */ + + dealloc_fde_cie_list_internal(head_fde_ptr, + head_cie_ptr); + return res; + } + frame_ptr = cie_ptr_to_use->ci_cie_start + + cie_ptr_to_use->ci_length + + cie_ptr_to_use->ci_length_size + + cie_ptr_to_use->ci_extension_size; + continue; + } else { + /* this is an FDE, Frame Description Entry, see the Dwarf + Spec, section 6.4.1 */ + int res = 0; + Dwarf_Cie cie_ptr_to_use = 0; + Dwarf_Fde fde_ptr_to_use = 0; + + /* Do not call this twice on one prefix, as + prefix.cf_cie_id_addr is altered as a side effect. */ + Dwarf_Small *cieptr_val = + get_cieptr_given_offset(prefix.cf_cie_id, + use_gnu_cie_calc, + section_ptr, + prefix.cf_cie_id_addr); + + res = dwarf_find_existing_cie_ptr(cieptr_val, + cur_cie_ptr, + &cie_ptr_to_use, + head_cie_ptr); + if (res == DW_DLV_OK) { + cur_cie_ptr = cie_ptr_to_use; + /* Ok. Seen CIE already. */ + } else if (res == DW_DLV_NO_ENTRY) { + res = dwarf_create_cie_from_start(dbg, + cieptr_val, + section_ptr, + section_index, + section_length, + frame_ptr_end, + cie_id_value, + cie_count, + use_gnu_cie_calc, + &cie_ptr_to_use, + error); + if (res == DW_DLV_ERROR) { + dealloc_fde_cie_list_internal(head_fde_ptr, + head_cie_ptr); + return res; + } else if (res == DW_DLV_NO_ENTRY) { + return res; + } + ++cie_count; + chain_up_cie(cie_ptr_to_use, &head_cie_ptr, + &tail_cie_ptr); + cur_cie_ptr = tail_cie_ptr; + + } else { + /* DW_DLV_ERROR */ + return res; + } + + res = dwarf_create_fde_from_after_start(dbg, + &prefix, + section_ptr, + frame_ptr, + use_gnu_cie_calc, + cie_ptr_to_use, + &fde_ptr_to_use, + error); + if (res == DW_DLV_ERROR) { + return res; + } + chain_up_fde(fde_ptr_to_use, &head_fde_ptr, &cur_fde_ptr); + fde_count++; + /* ASSERT: DW_DLV_OK. */ + frame_ptr = fde_ptr_to_use->fd_fde_start + + fde_ptr_to_use->fd_length + + fde_ptr_to_use->fd_length_size + + fde_ptr_to_use->fd_extension_size; + continue; + + } + + } + + /* Now build list of CIEs from the list. */ + if (cie_count > 0) { + cie_list_ptr = (Dwarf_Cie *) + _dwarf_get_alloc(dbg, DW_DLA_LIST, cie_count); + } else { + dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); + return (DW_DLV_NO_ENTRY); + } + if (cie_list_ptr == NULL) { + dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + cur_cie_ptr = head_cie_ptr; + for (i = 0; i < cie_count; i++) { + *(cie_list_ptr + i) = cur_cie_ptr; + cur_cie_ptr = cur_cie_ptr->ci_next; + } + + + + /* Now build array of FDEs from the list. */ + if (fde_count > 0) { + fde_list_ptr = (Dwarf_Fde *) + _dwarf_get_alloc(dbg, DW_DLA_LIST, fde_count); + } else { + dwarf_fde_cie_list_dealloc(dbg, cie_list_ptr, cie_count, + /* fde_data */ 0, + /* fde_element_count */ 0); + dealloc_fde_cie_list_internal(head_fde_ptr, /* head cie_ptr + */ + 0); + return (DW_DLV_NO_ENTRY); + } + if (fde_list_ptr == NULL) { + dwarf_fde_cie_list_dealloc(dbg, cie_list_ptr, cie_count, + /* fde_data */ 0, + /* fde_element_count */ 0); + dealloc_fde_cie_list_internal(head_fde_ptr, /* head cie_ptr + */ + 0); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + cur_fde_ptr = head_fde_ptr; + for (i = 0; i < fde_count; i++) { + *(fde_list_ptr + i) = cur_fde_ptr; + cur_fde_ptr = cur_fde_ptr->fd_next; + } + + + /* Return arguments. */ + *cie_data = cie_list_ptr; + *cie_element_count = cie_count; + dbg->de_cie_data = cie_list_ptr; + dbg->de_cie_count = cie_count; + + *fde_data = fde_list_ptr; + *fde_element_count = fde_count; + dbg->de_fde_data = fde_list_ptr; + dbg->de_fde_count = fde_count; + + /* Sort the list by the address so that dwarf_get_fde_at_pc() can + binary search this list. */ + qsort((void *) fde_list_ptr, fde_count, sizeof(Dwarf_Ptr), + qsort_compare); + + return (DW_DLV_OK); +} + +/* Internal function, not called by consumer code. + 'prefix' has accumulated the info up thru the cie-id + and now we consume the rest and build a Dwarf_Cie_s structure. +*/ +int +dwarf_create_cie_from_after_start(Dwarf_Debug dbg, + struct cie_fde_prefix_s *prefix, + Dwarf_Small * section_pointer, + Dwarf_Small * frame_ptr, + Dwarf_Unsigned cie_count, + int use_gnu_cie_calc, + Dwarf_Cie * cie_ptr_out, + Dwarf_Error * error) +{ + Dwarf_Cie new_cie = 0; + + /* egcs-1.1.2 .eh_frame uses 0 as the distinguishing id. sgi uses + -1 (in .debug_frame). .eh_frame not quite identical to + .debug_frame */ + Dwarf_Small eh_fde_encoding = 0; + Dwarf_Small *augmentation = 0; + Dwarf_Sword data_alignment_factor = -1; + Dwarf_Word code_alignment_factor = 4; + Dwarf_Unsigned return_address_register = 31; + int local_length_size = 0; + Dwarf_Word leb128_length = 0; + Dwarf_Unsigned cie_aug_data_len = 0; + Dwarf_Small *cie_aug_data = 0; + Dwarf_Addr gnu_personality_handler_addr = 0; + unsigned char gnu_personality_handler_encoding = 0; + unsigned char gnu_lsda_encoding = 0; + unsigned char gnu_fde_begin_encoding = 0; + + + enum Dwarf_augmentation_type augt = aug_unknown; + + + /* this is a CIE, Common Information Entry: See the dwarf spec, + section 6.4.1 */ + Dwarf_Small version = *(Dwarf_Small *) frame_ptr; + + frame_ptr++; + if (version != DW_CIE_VERSION && version != DW_CIE_VERSION3) { + _dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD); + return (DW_DLV_ERROR); + } + + augmentation = frame_ptr; + frame_ptr = frame_ptr + strlen((char *) frame_ptr) + 1; + augt = _dwarf_get_augmentation_type(dbg, + augmentation, use_gnu_cie_calc); + if (augt == aug_eh) { + /* REFERENCED *//* Not used in this instance */ + Dwarf_Unsigned exception_table_addr; + + /* this is per egcs-1.1.2 as on RH 6.0 */ + READ_UNALIGNED(dbg, exception_table_addr, + Dwarf_Unsigned, frame_ptr, local_length_size); + frame_ptr += local_length_size; + } + { + Dwarf_Unsigned lreg = 0; + unsigned long size = 0; + + DECODE_LEB128_UWORD(frame_ptr, lreg); + code_alignment_factor = (Dwarf_Word) lreg; + + data_alignment_factor = + (Dwarf_Sword) _dwarf_decode_s_leb128(frame_ptr, + &leb128_length); + + frame_ptr = frame_ptr + leb128_length; + + return_address_register = + _dwarf_get_return_address_reg(frame_ptr, version, &size); + if (return_address_register > DW_FRAME_LAST_REG_NUM) { + _dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR); + return (DW_DLV_ERROR); + } + frame_ptr += size; + } + switch (augt) { + case aug_empty_string: + break; + case aug_irix_mti_v1: + break; + case aug_irix_exception_table:{ + Dwarf_Unsigned lreg = 0; + Dwarf_Word length_of_augmented_fields; + + /* Decode the length of augmented fields. */ + DECODE_LEB128_UWORD(frame_ptr, lreg); + length_of_augmented_fields = (Dwarf_Word) lreg; + + + /* set the frame_ptr to point at the instruction start. */ + frame_ptr += length_of_augmented_fields; + } + break; + + case aug_eh:{ + + int err = 0; + unsigned long increment = 0; + + if (!use_gnu_cie_calc) { + /* This should be impossible. */ + _dwarf_error(dbg, error, + DW_DLE_FRAME_AUGMENTATION_UNKNOWN); + return DW_DLV_ERROR; + } + + err = get_gcc_eh_augmentation(dbg, frame_ptr, &increment, + augt, + prefix->cf_section_ptr, + &eh_fde_encoding, + (char *) augmentation); + if (err == DW_DLV_ERROR) { + _dwarf_error(dbg, error, + DW_DLE_FRAME_AUGMENTATION_UNKNOWN); + return DW_DLV_ERROR; + } + frame_ptr += increment; + break; + } + case aug_gcc_eh_z:{ + /* Here we have Augmentation Data Length (uleb128) followed + by Augmentation Data bytes. */ + int res; + Dwarf_Unsigned adlen = 0; + + DECODE_LEB128_UWORD(frame_ptr, adlen); + cie_aug_data_len = adlen; + cie_aug_data = frame_ptr; + res = gnu_aug_encodings(dbg, + (char *) augmentation, + cie_aug_data, + cie_aug_data_len, + &gnu_personality_handler_encoding, + &gnu_lsda_encoding, + &gnu_fde_begin_encoding, + &gnu_personality_handler_addr); + if (res != DW_DLV_OK) { + _dwarf_error(dbg, error, + DW_DLE_FRAME_AUGMENTATION_UNKNOWN); + return res; + } + + + frame_ptr += adlen; + break; + } + default:{ + /* We do not understand the augmentation string. No + assumption can be made about any fields other than what + we have already read. */ + frame_ptr = prefix->cf_start_addr + + prefix->cf_length + prefix->cf_local_length_size + + prefix->cf_local_extension_size; + /* FIX -- What are the values of data_alignment_factor, + code_alignement_factor, return_address_register and + instruction start? They were clearly uninitalized in the + previous version and I am leaving them the same way. */ + break; + } + } /* End switch on augmentation type. */ + + new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1); + if (new_cie == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + new_cie->ci_cie_version_number = version; + new_cie->ci_initial_table = NULL; + new_cie->ci_length = (Dwarf_Word) prefix->cf_length; + new_cie->ci_length_size = prefix->cf_local_length_size; + new_cie->ci_extension_size = prefix->cf_local_extension_size; + new_cie->ci_augmentation = (char *) augmentation; + + new_cie->ci_data_alignment_factor = + (Dwarf_Sbyte) data_alignment_factor; + new_cie->ci_code_alignment_factor = + (Dwarf_Small) code_alignment_factor; + new_cie->ci_return_address_register = return_address_register; + new_cie->ci_cie_start = prefix->cf_start_addr; + new_cie->ci_cie_instr_start = frame_ptr; + new_cie->ci_dbg = dbg; + new_cie->ci_augmentation_type = augt; + new_cie->ci_gnu_eh_augmentation_len = cie_aug_data_len; + new_cie->ci_gnu_eh_augmentation_bytes = cie_aug_data; + new_cie->ci_gnu_personality_handler_encoding = + gnu_personality_handler_encoding; + new_cie->ci_gnu_personality_handler_addr = + gnu_personality_handler_addr; + new_cie->ci_gnu_lsda_encoding = gnu_lsda_encoding; + new_cie->ci_gnu_fde_begin_encoding = gnu_fde_begin_encoding; + + new_cie->ci_index = cie_count; + new_cie->ci_section_ptr = prefix->cf_section_ptr; + + *cie_ptr_out = new_cie; + return DW_DLV_OK; + +} + + +/* Internal function, not called by consumer code. + 'prefix' has accumulated the info up thru the cie-id + and now we consume the rest and build a Dwarf_Fde_s structure. +*/ + +int +dwarf_create_fde_from_after_start(Dwarf_Debug dbg, + struct cie_fde_prefix_s *prefix, + Dwarf_Small * section_pointer, + Dwarf_Small * frame_ptr, + int use_gnu_cie_calc, + Dwarf_Cie cie_ptr_in, + Dwarf_Fde * fde_ptr_out, + Dwarf_Error * error) +{ + Dwarf_Fde new_fde = 0; + Dwarf_Cie cieptr = cie_ptr_in; + Dwarf_Small *saved_frame_ptr = 0; + + Dwarf_Small *initloc = frame_ptr; + Dwarf_Signed offset_into_exception_tables + /* must be min dwarf_sfixed in size */ + = (Dwarf_Signed) DW_DLX_NO_EH_OFFSET; + Dwarf_Small *fde_aug_data = 0; + Dwarf_Unsigned fde_aug_data_len = 0; + Dwarf_Addr cie_base_offset = prefix->cf_cie_id; + Dwarf_Addr initial_location = 0; /* must be min de_pointer_size + bytes in size */ + Dwarf_Addr address_range = 0; /* must be min de_pointer_size + bytes in size */ + + enum Dwarf_augmentation_type augt = cieptr->ci_augmentation_type; + + if (augt == aug_gcc_eh_z) { + /* If z augmentation this is eh_frame, and initial_location and + address_range in the FDE are read according to the CIE + augmentation string instructions. */ + + { + Dwarf_Small *fp_updated = 0; + int res = res = read_encoded_ptr(dbg, + section_pointer, + frame_ptr, + cieptr-> + ci_gnu_fde_begin_encoding, + &initial_location, + &fp_updated); + + if (res != DW_DLV_OK) { + _dwarf_error(dbg, error, + DW_DLE_FRAME_AUGMENTATION_UNKNOWN); + return DW_DLV_ERROR; + } + frame_ptr = fp_updated; + /* For the address-range it makes no sense to be + pc-relative, so we turn it off with a section_pointer of + NULL. Masking off DW_EH_PE_pcrel from the + ci_gnu_fde_begin_encoding in this call would also work + to turn off DW_EH_PE_pcrel. */ + res = read_encoded_ptr(dbg, (Dwarf_Small *) NULL, + frame_ptr, + cieptr->ci_gnu_fde_begin_encoding, + &address_range, &fp_updated); + if (res != DW_DLV_OK) { + _dwarf_error(dbg, error, + DW_DLE_FRAME_AUGMENTATION_UNKNOWN); + return DW_DLV_ERROR; + } + frame_ptr = fp_updated; + } + { + Dwarf_Unsigned adlen = 0; + + DECODE_LEB128_UWORD(frame_ptr, adlen); + fde_aug_data_len = adlen; + fde_aug_data = frame_ptr; + frame_ptr += adlen; + } + + } else { + READ_UNALIGNED(dbg, initial_location, Dwarf_Addr, + frame_ptr, dbg->de_pointer_size); + frame_ptr += dbg->de_pointer_size; + + READ_UNALIGNED(dbg, address_range, Dwarf_Addr, + frame_ptr, dbg->de_pointer_size); + frame_ptr += dbg->de_pointer_size; + } + + + + + + switch (augt) { + case aug_irix_mti_v1: + case aug_empty_string: + break; + case aug_irix_exception_table:{ + Dwarf_Unsigned lreg = 0; + Dwarf_Word length_of_augmented_fields = 0; + + DECODE_LEB128_UWORD(frame_ptr, lreg); + length_of_augmented_fields = (Dwarf_Word) lreg; + + saved_frame_ptr = frame_ptr; + /* The first word is an offset into exception tables. + Defined as a 32bit offset even for CC -64. */ + READ_UNALIGNED(dbg, offset_into_exception_tables, + Dwarf_Addr, frame_ptr, sizeof(Dwarf_sfixed)); + SIGN_EXTEND(offset_into_exception_tables, + sizeof(Dwarf_sfixed)); + frame_ptr = saved_frame_ptr + length_of_augmented_fields; + } + break; + case aug_eh:{ + Dwarf_Unsigned eh_table_value = 0; + + if (!use_gnu_cie_calc) { + /* This should be impossible. */ + _dwarf_error(dbg, error, + DW_DLE_FRAME_AUGMENTATION_UNKNOWN); + return DW_DLV_ERROR; + } + + /* gnu eh fde case. we do not need to do anything */ + /*REFERENCED*/ /* Not used in this instance of the + macro */ + READ_UNALIGNED(dbg, eh_table_value, + Dwarf_Unsigned, frame_ptr, + dbg->de_pointer_size); + frame_ptr += dbg->de_pointer_size; + } + break; + + case aug_gcc_eh_z:{ + /* The Augmentation Data Length is here, followed by the + Augmentation Data bytes themselves. */ + } + break; + case aug_past_last: + break; + case aug_unknown: + _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); + return DW_DLV_ERROR; + } /* End switch on augmentation type */ + new_fde = (Dwarf_Fde) _dwarf_get_alloc(dbg, DW_DLA_FDE, 1); + if (new_fde == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + new_fde->fd_length = prefix->cf_length; + new_fde->fd_length_size = prefix->cf_local_length_size; + new_fde->fd_extension_size = prefix->cf_local_extension_size; + new_fde->fd_cie_offset = cie_base_offset; + new_fde->fd_cie_index = cieptr->ci_index; + new_fde->fd_cie = cieptr; + new_fde->fd_initial_location = initial_location; + new_fde->fd_initial_loc_pos = initloc; + new_fde->fd_address_range = address_range; + new_fde->fd_fde_start = prefix->cf_start_addr; + new_fde->fd_fde_instr_start = frame_ptr; + new_fde->fd_dbg = dbg; + new_fde->fd_offset_into_exception_tables = + offset_into_exception_tables; + + new_fde->fd_section_ptr = prefix->cf_section_ptr; + new_fde->fd_section_index = prefix->cf_section_index; + new_fde->fd_section_length = prefix->cf_section_length; + + new_fde->fd_gnu_eh_augmentation_bytes = fde_aug_data; + new_fde->fd_gnu_eh_augmentation_len = fde_aug_data_len; + + *fde_ptr_out = new_fde; + return DW_DLV_OK; +} + +/* called by qsort to compare FDE entries. + Consumer code expects the array of FDE pointers to be in address order. +*/ +static int +qsort_compare(const void *elem1, const void *elem2) +{ + Dwarf_Fde fde1 = *(Dwarf_Fde *) elem1; + Dwarf_Fde fde2 = *(Dwarf_Fde *) elem2; + Dwarf_Addr addr1 = fde1->fd_initial_location; + Dwarf_Addr addr2 = fde2->fd_initial_location; + + if (addr1 < addr2) { + return -1; + } else if (addr1 > addr2) { + return 1; + } + return 0; +} + + +/* Read in the common cie/fde prefix, including reading + * the cie-value which shows which this is: cie or fde. + * */ +int +dwarf_read_cie_fde_prefix(Dwarf_Debug dbg, + Dwarf_Small * frame_ptr_in, + Dwarf_Small * section_ptr_in, + Dwarf_Unsigned section_index_in, + Dwarf_Unsigned section_length_in, + struct cie_fde_prefix_s *data_out, + Dwarf_Error * error) +{ + Dwarf_Unsigned length = 0; + int local_length_size = 0; + int local_extension_size = 0; + Dwarf_Small *frame_ptr = frame_ptr_in; + Dwarf_Small *cie_ptr_addr = 0; + Dwarf_Unsigned cie_id = 0; + + /* READ_AREA_LENGTH updates frame_ptr for consumed bytes */ + READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, + frame_ptr, local_length_size, + local_extension_size); + + if (length % local_length_size != 0) { + _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); + return (DW_DLV_ERROR); + } + + if (length == 0) { + /* nul bytes at end of section, seen at end of egcs eh_frame + sections (in a.out). Take this as meaning no more CIE/FDE + data. We should be very close to end of section. */ + return DW_DLV_NO_ENTRY; + } + + cie_ptr_addr = frame_ptr; + READ_UNALIGNED(dbg, cie_id, Dwarf_Unsigned, + frame_ptr, local_length_size); + SIGN_EXTEND(cie_id, local_length_size); + frame_ptr += local_length_size; + + data_out->cf_start_addr = frame_ptr_in; + data_out->cf_addr_after_prefix = frame_ptr; + + data_out->cf_length = length; + data_out->cf_local_length_size = local_length_size; + data_out->cf_local_extension_size = local_extension_size; + data_out->cf_cie_id = cie_id; + data_out->cf_cie_id_addr = cie_ptr_addr; + data_out->cf_section_ptr = section_ptr_in; + data_out->cf_section_index = section_index_in; + data_out->cf_section_length = section_length_in; + return DW_DLV_OK; +} + +/* On various errors previously-allocated CIEs and FDEs + must be cleaned up. + This helps avoid leaks in case of errors. +*/ +static void +dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr, + Dwarf_Cie head_cie_ptr) +{ + Dwarf_Fde curfde = 0; + Dwarf_Cie curcie = 0; + Dwarf_Fde nextfde = 0; + Dwarf_Cie nextcie = 0; + + for (curfde = head_fde_ptr; curfde; curfde = nextfde) { + nextfde = curfde->fd_next; + dwarf_dealloc(curfde->fd_dbg, curfde, DW_DLA_FDE); + } + for (curcie = head_cie_ptr; curcie; curcie = nextcie) { + Dwarf_Frame frame = curcie->ci_initial_table; + + nextcie = curcie->ci_next; + if (frame) + dwarf_dealloc(curcie->ci_dbg, frame, DW_DLA_FRAME); + dwarf_dealloc(curcie->ci_dbg, curcie, DW_DLA_CIE); + } +} + +/* Find the cie whose id value is given: the id + * value is, per DWARF2/3, an offset in the section. + * For .debug_frame, zero is a legal offset. For + * GNU .eh_frame it is not a legal offset. + * 'cie_ptr' is a pointer into our section, not an offset. */ +static int +dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr, + Dwarf_Cie cur_cie_ptr, + Dwarf_Cie * cie_ptr_to_use_out, + Dwarf_Cie head_cie_ptr) +{ + Dwarf_Cie next = 0; + + if (cur_cie_ptr && cie_ptr == cur_cie_ptr->ci_cie_start) { + /* Usually, we use the same cie again and again. */ + *cie_ptr_to_use_out = cur_cie_ptr; + return DW_DLV_OK; + } + for (next = head_cie_ptr; next; next = next->ci_next) { + if (cie_ptr == next->ci_cie_start) { + *cie_ptr_to_use_out = next; + return DW_DLV_OK; + } + } + return DW_DLV_NO_ENTRY; +} + + +/* We have a valid cie_ptr_val that has not been + * turned into an internal Cie yet. Do so now. + * Returns DW_DLV_OK or DW_DLV_ERROR, never + * DW_DLV_NO_ENTRY. + + 'section_ptr' - Points to first byte of section data. + 'section_length' - Length of the section, in bytes. + 'frame_ptr_end' - Points 1-past last byte of section data. + * */ +static int +dwarf_create_cie_from_start(Dwarf_Debug dbg, + Dwarf_Small * cie_ptr_val, + Dwarf_Small * section_ptr, + Dwarf_Unsigned section_index, + Dwarf_Unsigned section_length, + Dwarf_Small * frame_ptr_end, + Dwarf_Unsigned cie_id_value, + Dwarf_Unsigned cie_count, + int use_gnu_cie_calc, + Dwarf_Cie * cie_ptr_to_use_out, + Dwarf_Error * error) +{ + struct cie_fde_prefix_s prefix; + int res = 0; + Dwarf_Small *frame_ptr = cie_ptr_val; + + if (frame_ptr < section_ptr || frame_ptr > frame_ptr_end) { + _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); + return DW_DLV_ERROR; + } + /* First read in the 'common prefix' to figure out what * we are to + do with this entry. IF it's not a cie * we are in big trouble. */ + memset(&prefix, 0, sizeof(prefix)); + res = dwarf_read_cie_fde_prefix(dbg, frame_ptr, section_ptr, + section_index, section_length, + &prefix, error); + if (res == DW_DLV_ERROR) { + return res; + } + if (res == DW_DLV_NO_ENTRY) { + /* error. */ + _dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR); + return DW_DLV_ERROR; + + } + + if (prefix.cf_cie_id != cie_id_value) { + _dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR); + return DW_DLV_ERROR; + } + frame_ptr = prefix.cf_addr_after_prefix; + res = dwarf_create_cie_from_after_start(dbg, + &prefix, + section_ptr, + frame_ptr, + cie_count, + use_gnu_cie_calc, + cie_ptr_to_use_out, error); + + return res; + +} + + +/* This is for gnu eh frames, the 'z' case. + We find the letter involved + Return the augmentation character and, if applicable, + the personality routine address. + + personality_routine_out - + if 'P' is augchar, is personality handler addr. + Otherwise is not set. + aug_data - if 'P' points to data space of the + aug_data_len - length of areas aug_data points to. + +*/ +#if 0 +/* For debugging only. */ +void +dump_bytes(Dwarf_Small * start, long len) +{ + Dwarf_Small *end = start + len; + Dwarf_Small *cur = start; + + for (; cur < end; cur++) { + printf(" byte %d, data %02x\n", (int) (cur - start), *cur); + } + +} +#endif +static int +gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation, + Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len, + unsigned char *pers_hand_enc_out, + unsigned char *lsda_enc_out, + unsigned char *fde_begin_enc_out, + Dwarf_Addr * gnu_pers_addr_out) +{ + char *nc = 0; + Dwarf_Small *cur_aug_p = aug_data; + Dwarf_Small *end_aug_p = aug_data + aug_data_len; + + for (nc = augmentation; *nc; ++nc) { + char c = *nc; + + switch (c) { + case 'z': + /* Means that the augmentation data is present. */ + continue; + + case 'S': + /* Indicates this is a signal stack frame. Debuggers have to do + special handling. We don't need to do more than print this flag at + the right time, though (see dwarfdump where it prints the augmentation + string). + A signal stack frame (in some OS's) can only be + unwound (backtraced) by knowing it is a signal stack frame + (perhaps by noticing the name of the function for the stack frame + if the name can be found somehow) and figuring + out (or knowing) how the kernel and libc pushed a structure + onto the stack and loading registers from that structure. + Totally different from normal stack unwinding. + This flag gives an unwinder a big leg up by decoupling the + 'hint: this is a stack frame' from knowledge like + the function name (the name might be unavailable at unwind time). + */ + break; + + case 'L': + if (cur_aug_p > end_aug_p) { + return DW_DLV_ERROR; + } + *lsda_enc_out = *(unsigned char *) cur_aug_p; + ++cur_aug_p; + break; + case 'R': + /* Followed by a one byte argument giving the + pointer encoding for the address pointers in the fde. */ + if (cur_aug_p >= end_aug_p) { + return DW_DLV_ERROR; + } + *fde_begin_enc_out = *(unsigned char *) cur_aug_p; + ++cur_aug_p; + break; + case 'P':{ + int res = 0; + Dwarf_Small *updated_aug_p = 0; + unsigned char encoding = 0; + + if (cur_aug_p >= end_aug_p) { + return DW_DLV_ERROR; + } + encoding = *(unsigned char *) cur_aug_p; + *pers_hand_enc_out = encoding; + ++cur_aug_p; + if (cur_aug_p > end_aug_p) { + return DW_DLV_ERROR; + } + /* DW_EH_PE_pcrel makes no sense here, so we turn it + off via a section pointer of NULL. */ + res = read_encoded_ptr(dbg, + (Dwarf_Small *) NULL, + cur_aug_p, + encoding, + gnu_pers_addr_out, + &updated_aug_p); + if (res != DW_DLV_OK) { + return res; + } + cur_aug_p = updated_aug_p; + if (cur_aug_p > end_aug_p) { + return DW_DLV_ERROR; + } + } + break; + default: + return DW_DLV_ERROR; + + } + } + + return DW_DLV_OK; +} + +/* Given augmentation character (the encoding) giving the +address format, read the address from input_field +and return an incremented value 1 past the input bytes of the +address. +Push the address read back thru the *addr pointer. +See LSB (Linux Standar Base) exception handling documents. +*/ +static int +read_encoded_ptr(Dwarf_Debug dbg, + Dwarf_Small * section_pointer, + Dwarf_Small * input_field, + int gnu_encoding, + Dwarf_Unsigned * addr, + Dwarf_Small ** input_field_updated) +{ + Dwarf_Word length = 0; + int value_type = gnu_encoding & 0xf; + Dwarf_Small *input_field_original = input_field; + + if (gnu_encoding == 0xff) { + /* There is no data here. */ + + *addr = 0; + *input_field_updated = input_field; + /* Should we return DW_DLV_NO_ENTRY? */ + return DW_DLV_OK; + } + switch (value_type) { + case DW_EH_PE_absptr:{ + /* value_type is zero. Treat as pointer size of the object. + */ + Dwarf_Unsigned ret_value = 0; + + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + input_field, dbg->de_pointer_size); + *addr = ret_value; + *input_field_updated = input_field + dbg->de_pointer_size; + } + break; + case DW_EH_PE_uleb128:{ + Dwarf_Unsigned val = _dwarf_decode_u_leb128(input_field, + &length); + + *addr = val; + *input_field_updated = input_field + length; + } + break; + case DW_EH_PE_udata2:{ + Dwarf_Unsigned ret_value = 0; + + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + input_field, 2); + *addr = ret_value; + *input_field_updated = input_field + 2; + } + break; + + case DW_EH_PE_udata4:{ + + Dwarf_Unsigned ret_value = 0; + + /* ASSERT: sizeof(Dwarf_ufixed) == 4 */ + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + input_field, sizeof(Dwarf_ufixed)); + *addr = ret_value; + *input_field_updated = input_field + sizeof(Dwarf_ufixed); + } + break; + + case DW_EH_PE_udata8:{ + Dwarf_Unsigned ret_value = 0; + + /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */ + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + input_field, sizeof(Dwarf_Unsigned)); + *addr = ret_value; + *input_field_updated = input_field + sizeof(Dwarf_Unsigned); + } + break; + + case DW_EH_PE_sleb128:{ + Dwarf_Signed val = _dwarf_decode_s_leb128(input_field, + &length); + + *addr = (Dwarf_Unsigned) val; + *input_field_updated = input_field + length; + } + break; + case DW_EH_PE_sdata2:{ + Dwarf_Unsigned val = 0; + + READ_UNALIGNED(dbg, val, Dwarf_Unsigned, input_field, 2); + SIGN_EXTEND(val, 2); + *addr = (Dwarf_Unsigned) val; + *input_field_updated = input_field + 2; + } + break; + + case DW_EH_PE_sdata4:{ + Dwarf_Unsigned val = 0; + + /* ASSERT: sizeof(Dwarf_ufixed) == 4 */ + READ_UNALIGNED(dbg, val, + Dwarf_Unsigned, input_field, + sizeof(Dwarf_ufixed)); + SIGN_EXTEND(val, sizeof(Dwarf_ufixed)); + *addr = (Dwarf_Unsigned) val; + *input_field_updated = input_field + sizeof(Dwarf_ufixed); + } + break; + case DW_EH_PE_sdata8:{ + Dwarf_Unsigned val = 0; + + /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */ + READ_UNALIGNED(dbg, val, + Dwarf_Unsigned, input_field, + sizeof(Dwarf_Unsigned)); + *addr = (Dwarf_Unsigned) val; + *input_field_updated = input_field + sizeof(Dwarf_Unsigned); + } + break; + default: + return DW_DLV_ERROR; + + }; + /* The ELF ABI for gnu does not document the meaning of + DW_EH_PE_pcrel, which is awkward. It apparently means the value + we got above is pc-relative (meaning section-relative), so we + adjust the value. Section_pointer may be null if it is known + DW_EH_PE_pcrel cannot apply, such as for .debug_frame or for an + address-range value. */ + if (section_pointer && ((gnu_encoding & 0x70) == DW_EH_PE_pcrel)) { + /* Address (*addr) above is pc relative with respect to a + section. Add to the offset the base address (from elf) of + section and the distance of the field we are reading from + the section-beginning to get the actual address. */ + /* ASSERT: input_field_original >= section_pointer */ + Dwarf_Unsigned distance = + input_field_original - section_pointer; + *addr += dbg->de_debug_frame_eh_addr + distance; + } + + return DW_DLV_OK; +} + + + + +/* + All augmentation string checking done here now. + + For .eh_frame, gcc from 3.3 uses the z style, earlier used + only "eh" as augmentation. We don't yet handle + decoding .eh_frame with the z style extensions like L P. + + These are nasty heuristics, but then that's life + as augmentations are implementation specific. +*/ +/* ARGSUSED */ +enum Dwarf_augmentation_type +_dwarf_get_augmentation_type(Dwarf_Debug dbg, + Dwarf_Small * augmentation_string, + int is_gcc_eh_frame) +{ + enum Dwarf_augmentation_type t = aug_unknown; + char *ag_string = (char *) augmentation_string; + + if (ag_string[0] == 0) { + /* Empty string. We'll just guess that we know what this means: + standard dwarf2/3 with no implementation-defined fields. */ + t = aug_empty_string; + } else if (strcmp(ag_string, DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) { + /* The string is "mti v1". Used internally at SGI, probably + never shipped. Replaced by "z". Treat like 'nothing + special'. */ + t = aug_irix_mti_v1; + } else if (ag_string[0] == 'z') { + /* If it's IRIX cc, z means aug_irix_exception_table. z1 z2 + were designed as for IRIX CC, but never implemented */ + /* If it's gcc, z may be any of several things. "z" or z + followed optionally followed by one or more of L R P, each + of which means a value may be present. Should be in eh_frame + only, I think. */ + if (is_gcc_eh_frame) { + t = aug_gcc_eh_z; + } else if (ag_string[1] == 0) { + /* This is the normal IRIX C++ case, where there is an + offset into a table in each fde. The table being for + IRIX CC exception handling. */ + /* DW_CIE_AUGMENTER_STRING_V0 "z" */ + t = aug_irix_exception_table; + } /* Else unknown. */ + } else if (strncmp(ag_string, "eh", 2) == 0) { + /* gcc .eh_frame augmentation for egcs and gcc 2.x, at least + for x86. */ + t = aug_eh; + } + return t; +} + +/* Using augmentation, and version + read in the augmentation data for GNU eh. + + Return DW_DLV_OK if we succeeded, + DW_DLV_ERR if we fail. + + On success, update 'size_of_augmentation_data' with + the length of the fields that are part of augmentation (so the + caller can increment frame_ptr appropriately). + + 'frame_ptr' points within section. + 'section_pointer' points to section base address in memory. +*/ +/* ARGSUSED */ +static int +get_gcc_eh_augmentation(Dwarf_Debug dbg, Dwarf_Small * frame_ptr, + unsigned long *size_of_augmentation_data, + enum Dwarf_augmentation_type augtype, + Dwarf_Small * section_pointer, + Dwarf_Small * fde_eh_encoding_out, + char *augmentation) +{ + char *suffix = 0; + unsigned long augdata_size = 0; + + if (augtype == aug_gcc_eh_z) { + /* Has leading 'z'. */ + Dwarf_Word leb128_length = 0; + + /* Dwarf_Unsigned eh_value = */ + _dwarf_decode_u_leb128(frame_ptr, &leb128_length); + augdata_size += leb128_length; + frame_ptr += leb128_length; + suffix = augmentation + 1; + } else { + /* Prefix is 'eh'. As in gcc 3.2. No suffix present + apparently. */ + suffix = augmentation + 2; + } + for (; *suffix; ++suffix) { + /* We have no idea what this is as yet. Some extensions beyond + dwarf exist which we do not yet handle. */ + return DW_DLV_ERROR; + + } + + *size_of_augmentation_data = augdata_size; + return DW_DLV_OK; +} + + +/* Make the 'cie_id_addr' consistent across .debug_frame and .eh_frame. + Calculate a pointer into section bytes given a cie_id, which is + trivial for .debug_frame, but a bit more work for .eh_frame. +*/ +static Dwarf_Small * +get_cieptr_given_offset(Dwarf_Unsigned cie_id_value, + int use_gnu_cie_calc, + Dwarf_Small * section_ptr, + Dwarf_Small * cie_id_addr) +{ + Dwarf_Small *cieptr = 0; + + if (use_gnu_cie_calc) { + /* cie_id value is offset, in section, of the cie_id itself, to + use vm ptr of the value, less the value, to get to the cie + itself. In addition, munge *cie_id_addr to look *as if* it + was from real dwarf. */ + cieptr = (Dwarf_Small *) ((Dwarf_Unsigned) cie_id_addr) - + ((Dwarf_Unsigned) cie_id_value); + } else { + /* Traditional dwarf section offset is in cie_id */ + cieptr = (section_ptr + cie_id_value); + } + return cieptr; +} + +/* To properly release all spaced used. + Earlier approaches (before July 15, 2005) + letting client do the dealloc directly left + some data allocated. + This is directly called by consumer code. +*/ +void +dwarf_fde_cie_list_dealloc(Dwarf_Debug dbg, + Dwarf_Cie * cie_data, + Dwarf_Signed cie_element_count, + Dwarf_Fde * fde_data, + Dwarf_Signed fde_element_count) +{ + Dwarf_Signed i = 0; + + for (i = 0; i < cie_element_count; ++i) { + Dwarf_Frame frame = cie_data[i]->ci_initial_table; + + if (frame) + dwarf_dealloc(dbg, frame, DW_DLA_FRAME); + dwarf_dealloc(dbg, cie_data[i], DW_DLA_CIE); + } + for (i = 0; i < fde_element_count; ++i) { + dwarf_dealloc(dbg, fde_data[i], DW_DLA_FDE); + } + if (cie_data) + dwarf_dealloc(dbg, cie_data, DW_DLA_LIST); + if (fde_data) + dwarf_dealloc(dbg, fde_data, DW_DLA_LIST); + +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame3.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame3.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,293 @@ +/* + + Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include +#include "dwarf_frame.h" +#include "dwarf_arange.h" /* using Arange as a way to build a + list */ + +/* + Used by rqs (an IRIX application). + Not needed except for that one application. + Should be moved to its own source file since + it is so rarely needed. + Returns DW_DLV_OK if returns the arrays. + Returns DW_DLV_NO_ENTRY if no section. ?? (How do I tell?) + Returns DW_DLV_ERROR if there is an error. + + Uses DW_FRAME_CFA_COL because IRIX is only DWARF2 + and that is what IRIX compilers and compatible + compilers support on IRIX. +*/ +int +_dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist, + Dwarf_Off ** offsetlist, + Dwarf_Signed * returncount, + Dwarf_Error * err) +{ + int retval = DW_DLV_OK; + int res; + Dwarf_Cie *cie_data; + Dwarf_Signed cie_count; + Dwarf_Fde *fde_data; + Dwarf_Signed fde_count; + Dwarf_Signed i; + Dwarf_Frame_Op *frame_inst; + Dwarf_Fde fdep; + Dwarf_Cie ciep; + Dwarf_Chain curr_chain = 0; + Dwarf_Chain head_chain = 0; + Dwarf_Chain prev_chain = 0; + Dwarf_Arange arange; + Dwarf_Unsigned arange_count = 0; + Dwarf_Addr *arange_addrs = 0; + Dwarf_Off *arange_offsets = 0; + + res = dwarf_get_fde_list(dbg, &cie_data, &cie_count, + &fde_data, &fde_count, err); + if (res != DW_DLV_OK) { + return res; + } + + res = + _dwarf_load_section(dbg, + dbg->de_debug_frame_index, + &dbg->de_debug_frame, err); + if (res != DW_DLV_OK) { + return res; + } + + for (i = 0; i < cie_count; i++) { + Dwarf_Off instoff = 0; + Dwarf_Signed initial_instructions_length = 0; + Dwarf_Small *instr_end = 0; + Dwarf_Sword icount = 0; + int j; + int dw_err; + + ciep = cie_data[i]; + instoff = ciep->ci_cie_instr_start - dbg->de_debug_frame; + initial_instructions_length = ciep->ci_length + + ciep->ci_length_size + ciep->ci_extension_size - + (ciep->ci_cie_instr_start - ciep->ci_cie_start); + instr_end = ciep->ci_cie_instr_start + + initial_instructions_length; + res = _dwarf_exec_frame_instr( /* make_instr */ true, + &frame_inst, + /* search_pc= */ false, + /* search_pc_val= */ 0, + /* location */ 0, + ciep->ci_cie_instr_start, + instr_end, + /* Dwarf_frame= */ 0, + /* cie= */ 0, + dbg, + DW_FRAME_CFA_COL, + &icount, &dw_err); + if (res == DW_DLV_ERROR) { + _dwarf_error(dbg, err, dw_err); + return (res); + } else if (res == DW_DLV_NO_ENTRY) { + continue; + } + + for (j = 0; j < icount; ++j) { + Dwarf_Frame_Op *finst = frame_inst + j; + + if (finst->fp_base_op == 0 && finst->fp_extended_op == 1) { + /* is DW_CFA_set_loc */ + Dwarf_Addr add = (Dwarf_Addr) finst->fp_offset; + Dwarf_Off off = finst->fp_instr_offset + instoff; + + arange = (Dwarf_Arange) + _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); + if (arange == NULL) { + _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + arange->ar_address = add; + arange->ar_info_offset = off; + arange_count++; + curr_chain = (Dwarf_Chain) + _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (curr_chain == NULL) { + _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + curr_chain->ch_item = arange; + if (head_chain == NULL) + head_chain = prev_chain = curr_chain; + else { + prev_chain->ch_next = curr_chain; + prev_chain = curr_chain; + } + } + } + dwarf_dealloc(dbg, frame_inst, DW_DLA_FRAME_BLOCK); + + } + for (i = 0; i < fde_count; i++) { + Dwarf_Small *instr_end = 0; + Dwarf_Sword icount = 0; + Dwarf_Signed instructions_length = 0; + Dwarf_Off instoff = 0; + Dwarf_Off off = 0; + Dwarf_Addr addr = 0; + int j; + int dw_err; + + fdep = fde_data[i]; + off = fdep->fd_initial_loc_pos - dbg->de_debug_frame; + addr = fdep->fd_initial_location; + arange = (Dwarf_Arange) + _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); + if (arange == NULL) { + _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + arange->ar_address = addr; + arange->ar_info_offset = off; + arange_count++; + curr_chain = (Dwarf_Chain) + _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (curr_chain == NULL) { + _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + curr_chain->ch_item = arange; + if (head_chain == NULL) + head_chain = prev_chain = curr_chain; + else { + prev_chain->ch_next = curr_chain; + prev_chain = curr_chain; + } + + + instoff = fdep->fd_fde_instr_start - dbg->de_debug_frame; + instructions_length = fdep->fd_length + + fdep->fd_length_size + fdep->fd_extension_size - + (fdep->fd_fde_instr_start - fdep->fd_fde_start); + instr_end = fdep->fd_fde_instr_start + instructions_length; + res = _dwarf_exec_frame_instr( /* make_instr */ true, + &frame_inst, + /* search_pc= */ false, + /* search_pc_val= */ 0, + /* location */ 0, + fdep->fd_fde_instr_start, + instr_end, + /* Dwarf_frame= */ 0, + /* cie= */ 0, + dbg, + DW_FRAME_CFA_COL, + &icount, &dw_err); + if (res == DW_DLV_ERROR) { + _dwarf_error(dbg, err, dw_err); + return (res); + } else if (res == DW_DLV_NO_ENTRY) { + continue; + } + + for (j = 0; j < icount; ++j) { + Dwarf_Frame_Op *finst2 = frame_inst + j; + + if (finst2->fp_base_op == 0 && finst2->fp_extended_op == 1) { + /* is DW_CFA_set_loc */ + Dwarf_Addr add = (Dwarf_Addr) finst2->fp_offset; + Dwarf_Off off = finst2->fp_instr_offset + instoff; + + arange = (Dwarf_Arange) + _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); + if (arange == NULL) { + _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + arange->ar_address = add; + arange->ar_info_offset = off; + arange_count++; + curr_chain = (Dwarf_Chain) + _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (curr_chain == NULL) { + _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + curr_chain->ch_item = arange; + if (head_chain == NULL) + head_chain = prev_chain = curr_chain; + else { + prev_chain->ch_next = curr_chain; + prev_chain = curr_chain; + } + + } + } + dwarf_dealloc(dbg, frame_inst, DW_DLA_FRAME_BLOCK); + + } + dwarf_dealloc(dbg, fde_data, DW_DLA_LIST); + dwarf_dealloc(dbg, cie_data, DW_DLA_LIST); + arange_addrs = (Dwarf_Addr *) + _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); + if (arange_addrs == NULL) { + _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + arange_offsets = (Dwarf_Off *) + _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); + if (arange_offsets == NULL) { + _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + curr_chain = head_chain; + for (i = 0; i < arange_count; i++) { + Dwarf_Arange ar = curr_chain->ch_item; + + arange_addrs[i] = ar->ar_address; + arange_offsets[i] = ar->ar_info_offset; + prev_chain = curr_chain; + curr_chain = curr_chain->ch_next; + dwarf_dealloc(dbg, ar, DW_DLA_ARANGE); + dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); + } + *returncount = arange_count; + *offsetlist = arange_offsets; + *addrlist = arange_addrs; + return retval; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_funcs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_funcs.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,140 @@ +/* + + Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_funcs.h" +#include "dwarf_global.h" + +int +dwarf_get_funcs(Dwarf_Debug dbg, + Dwarf_Func ** funcs, + Dwarf_Signed * ret_func_count, Dwarf_Error * error) +{ + int res; + + res = + _dwarf_load_section(dbg, + dbg->de_debug_funcnames_index, + &dbg->de_debug_funcnames, error); + if (res != DW_DLV_OK) { + return res; + } + + return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_funcnames, dbg->de_debug_funcnames_size, (Dwarf_Global **) funcs, /* type + punning, + Dwarf_Type + is + never + a + completed + type + */ + ret_func_count, + error, + DW_DLA_FUNC_CONTEXT, + DW_DLA_FUNC, + DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD, + DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR); + +} + +/* Deallocating fully requires deallocating the list + and all entries. But some internal data is + not exposed, so we need a function with internal knowledge. +*/ + +void +dwarf_funcs_dealloc(Dwarf_Debug dbg, Dwarf_Func * dwgl, + Dwarf_Signed count) +{ + _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl, + count, + DW_DLA_FUNC_CONTEXT, + DW_DLA_FUNC, DW_DLA_LIST); + return; +} + + + +int +dwarf_funcname(Dwarf_Func func_in, char **ret_name, Dwarf_Error * error) +{ + Dwarf_Global func = (Dwarf_Global) func_in; + + if (func == NULL) { + _dwarf_error(NULL, error, DW_DLE_FUNC_NULL); + return (DW_DLV_ERROR); + } + + *ret_name = (char *) (func->gl_name); + return DW_DLV_OK; +} + +int +dwarf_func_die_offset(Dwarf_Func func_in, + Dwarf_Off * return_offset, Dwarf_Error * error) +{ + Dwarf_Global func = (Dwarf_Global) func_in; + + return dwarf_global_die_offset(func, return_offset, error); +} + + +int +dwarf_func_cu_offset(Dwarf_Func func_in, + Dwarf_Off * return_offset, Dwarf_Error * error) +{ + Dwarf_Global func = (Dwarf_Global) func_in; + + return dwarf_global_cu_offset(func, return_offset, error); +} + + +int +dwarf_func_name_offsets(Dwarf_Func func_in, + char **ret_func_name, + Dwarf_Off * die_offset, + Dwarf_Off * cu_die_offset, Dwarf_Error * error) +{ + Dwarf_Global func = (Dwarf_Global) func_in; + + return dwarf_global_name_offsets(func, + ret_func_name, + die_offset, cu_die_offset, error); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_funcs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_funcs.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,42 @@ +/* + + Copyright (C) 2000, 2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + + +typedef struct Dwarf_Func_Context_s *Dwarf_Func_Context; + + +/* struct never completed: see dwarf_global.h */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_global.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_global.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,594 @@ +/* + + Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_global.h" + + +#ifdef __sgi /* __sgi should only be defined for + IRIX/MIPS. */ +/* The 'fixup' here intended for IRIX targets only. + With a 2+GB Elf64 IRIX executable (under 4GB in size), + some DIE offsets wrongly + got the 32bit upper bit sign extended. For the cu-header + offset in the .debug_pubnames section and in the + .debug_aranges section. + the 'varp' here is a pointer to an offset into .debug_info. + We fix up the offset here if it seems advisable.. + + As of June 2005 we have identified a series of mistakes + in ldx64 that can cause this (64 bit values getting passed + thru 32-bit signed knothole). +*/ +void +_dwarf_fix_up_offset_irix(Dwarf_Debug dbg, + Dwarf_Unsigned * varp, char *caller_site_name) +{ + + Dwarf_Unsigned var = *varp; + +#define UPPER33 0xffffffff80000000LL +#define LOWER32 0xffffffffLL + /* Restrict the hack to the known case. Upper 32 bits erroneously + sign extended from lower 32 upper bit. */ + if ((var & UPPER33) == UPPER33) { + var &= LOWER32; + /* Apply the fix. Dreadful hack. */ + *varp = var; + } +#undef UPPER33 +#undef LOWER32 + return; +} +#endif + + +int +dwarf_get_globals(Dwarf_Debug dbg, + Dwarf_Global ** globals, + Dwarf_Signed * return_count, Dwarf_Error * error) +{ + int res; + + res = + _dwarf_load_section(dbg, + dbg->de_debug_pubnames_index, + &dbg->de_debug_pubnames, error); + if (res != DW_DLV_OK) { + return res; + } + + + + return _dwarf_internal_get_pubnames_like_data(dbg, + dbg-> + de_debug_pubnames, + dbg-> + de_debug_pubnames_size, + globals, return_count, + error, + DW_DLA_GLOBAL_CONTEXT, + DW_DLA_GLOBAL, + DW_DLE_PUBNAMES_LENGTH_BAD, + DW_DLE_PUBNAMES_VERSION_ERROR); + +} + +/* Deallocating fully requires deallocating the list + and all entries. But some internal data is + not exposed, so we need a function with internal knowledge. +*/ + +void +dwarf_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl, + Dwarf_Signed count) +{ + _dwarf_internal_globals_dealloc(dbg, dwgl, + count, + DW_DLA_GLOBAL_CONTEXT, + DW_DLA_GLOBAL, DW_DLA_LIST); + return; +} + +void +_dwarf_internal_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl, + Dwarf_Signed count, + int context_code, + int global_code, int list_code) +{ + Dwarf_Signed i; + struct Dwarf_Global_Context_s *gcp = 0; + struct Dwarf_Global_Context_s *lastgcp = 0; + + for (i = 0; i < count; i++) { + Dwarf_Global dgb = dwgl[i]; + + gcp = dgb->gl_context; + + if (lastgcp != gcp) { + lastgcp = gcp; + dwarf_dealloc(dbg, gcp, context_code); + } + dwarf_dealloc(dbg, dgb, global_code); + } + dwarf_dealloc(dbg, dwgl, list_code); + return; +} + + +/* Sweeps the complete section. +*/ +int +_dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, + Dwarf_Small * section_data_ptr, + Dwarf_Unsigned section_length, + Dwarf_Global ** globals, + Dwarf_Signed * return_count, + Dwarf_Error * error, + int context_code, + int global_code, + int length_err_num, + int version_err_num) +{ + + + Dwarf_Small *pubnames_like_ptr = 0; + + + + /* + Points to the context for the current set of global names, and + contains information to identify the compilation-unit that the + set refers to. */ + Dwarf_Global_Context pubnames_context = 0; + + Dwarf_Half version = 0; + + /* + Offset from the start of compilation-unit for the current + global. */ + Dwarf_Off die_offset_in_cu = 0; + + Dwarf_Unsigned global_count = 0; + + /* Points to the current global read. */ + Dwarf_Global global = 0; + + /* + Used to chain the Dwarf_Global_s structs for creating contiguous + list of pointers to the structs. */ + Dwarf_Chain curr_chain = 0; + Dwarf_Chain prev_chain = 0; + Dwarf_Chain head_chain = 0; + + /* Points to contiguous block of Dwarf_Global's to be returned. */ + Dwarf_Global *ret_globals = 0; + + /* Temporary counter. */ + Dwarf_Unsigned i = 0; + + + + + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + /* We will eventually need the .debug_info data. Load it now. */ + if (!dbg->de_debug_info) { + int res = _dwarf_load_debug_info(dbg, error); + + if (res != DW_DLV_OK) { + return res; + } + } + + if (section_data_ptr == NULL) { + return (DW_DLV_NO_ENTRY); + } + + pubnames_like_ptr = section_data_ptr; + do { + Dwarf_Unsigned length = 0; + int local_extension_size = 0; + int local_length_size = 0; + + /* Some compilers emit padding at the end of each cu's area. + pubnames_ptr_past_end_cu records the true area end for this + cu's data. Essentially the length in the header and the 0 + terminator of the data are redundant information. The + dwarf2/3 spec does not mention what to do if the length is + past the 0 terminator. So we take any bytes left after the 0 + as padding and ignore them. */ + Dwarf_Small *pubnames_ptr_past_end_cu = 0; + + + pubnames_context = (Dwarf_Global_Context) + _dwarf_get_alloc(dbg, context_code, 1); + if (pubnames_context == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + /* READ_AREA_LENGTH updates pubnames_like_ptr for consumed + bytes */ + READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, + pubnames_like_ptr, local_length_size, + local_extension_size); + pubnames_context->pu_length_size = local_length_size; + pubnames_context->pu_extension_size = local_extension_size; + pubnames_context->pu_dbg = dbg; + + pubnames_ptr_past_end_cu = pubnames_like_ptr + length; + + READ_UNALIGNED(dbg, version, Dwarf_Half, + pubnames_like_ptr, sizeof(Dwarf_Half)); + pubnames_like_ptr += sizeof(Dwarf_Half); + if (version != CURRENT_VERSION_STAMP) { + _dwarf_error(dbg, error, version_err_num); + return (DW_DLV_ERROR); + } + + /* offset of CU header in debug section */ + READ_UNALIGNED(dbg, pubnames_context->pu_offset_of_cu_header, + Dwarf_Off, pubnames_like_ptr, + pubnames_context->pu_length_size); + pubnames_like_ptr += pubnames_context->pu_length_size; + + FIX_UP_OFFSET_IRIX_BUG(dbg, + pubnames_context->pu_offset_of_cu_header, + "pubnames cu header offset"); + + + READ_UNALIGNED(dbg, pubnames_context->pu_info_length, + Dwarf_Unsigned, pubnames_like_ptr, + pubnames_context->pu_length_size); + pubnames_like_ptr += pubnames_context->pu_length_size; + + if (pubnames_like_ptr > (section_data_ptr + section_length)) { + _dwarf_error(dbg, error, length_err_num); + return (DW_DLV_ERROR); + } + + /* read initial offset (of DIE within CU) of a pubname, final + entry is not a pair, just a zero offset */ + READ_UNALIGNED(dbg, die_offset_in_cu, Dwarf_Off, + pubnames_like_ptr, + pubnames_context->pu_length_size); + pubnames_like_ptr += pubnames_context->pu_length_size; + FIX_UP_OFFSET_IRIX_BUG(dbg, + die_offset_in_cu, "offset of die in cu"); + + /* loop thru pairs. DIE off with CU followed by string */ + while (die_offset_in_cu != 0) { + + /* Already read offset, pubnames_like_ptr now points to the + string */ + global = + (Dwarf_Global) _dwarf_get_alloc(dbg, global_code, 1); + if (global == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + global_count++; + + global->gl_context = pubnames_context; + + global->gl_named_die_offset_within_cu = die_offset_in_cu; + + global->gl_name = pubnames_like_ptr; + + pubnames_like_ptr = pubnames_like_ptr + + strlen((char *) pubnames_like_ptr) + 1; + + + /* finish off current entry chain */ + curr_chain = + (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (curr_chain == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + /* Put current global on singly_linked list. */ + curr_chain->ch_item = (Dwarf_Global) global; + + if (head_chain == NULL) + head_chain = prev_chain = curr_chain; + else { + prev_chain->ch_next = curr_chain; + prev_chain = curr_chain; + } + + /* read offset for the *next* entry */ + READ_UNALIGNED(dbg, die_offset_in_cu, Dwarf_Off, + pubnames_like_ptr, + pubnames_context->pu_length_size); + + pubnames_like_ptr += pubnames_context->pu_length_size; + FIX_UP_OFFSET_IRIX_BUG(dbg, + die_offset_in_cu, + "offset of next die in cu"); + + if (pubnames_like_ptr > (section_data_ptr + section_length)) { + _dwarf_error(dbg, error, length_err_num); + return (DW_DLV_ERROR); + } + } + /* ASSERT: die_offset_in_cu == 0 */ + if (pubnames_like_ptr > pubnames_ptr_past_end_cu) { + /* This is some kind of error. This simply cannot happen. + The encoding is wrong or the length in the header for + this cu's contribution is wrong. */ + _dwarf_error(dbg, error, length_err_num); + return (DW_DLV_ERROR); + + } + /* If there is some kind of padding at the end of the section, + as emitted by some compilers, skip over that padding and + simply ignore the bytes thus passed-over. With most + compilers, pubnames_like_ptr == pubnames_ptr_past_end_cu at + this point */ + pubnames_like_ptr = pubnames_ptr_past_end_cu; + + } while (pubnames_like_ptr < (section_data_ptr + section_length)); + + /* Points to contiguous block of Dwarf_Global's. */ + ret_globals = (Dwarf_Global *) + _dwarf_get_alloc(dbg, DW_DLA_LIST, global_count); + if (ret_globals == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + /* + Store pointers to Dwarf_Global_s structs in contiguous block, + and deallocate the chain. */ + curr_chain = head_chain; + for (i = 0; i < global_count; i++) { + *(ret_globals + i) = curr_chain->ch_item; + prev_chain = curr_chain; + curr_chain = curr_chain->ch_next; + dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); + } + + *globals = ret_globals; + *return_count = (Dwarf_Signed) global_count; + return DW_DLV_OK; +} + + +/* + Given a pubnames entry (or other like section entry) + return thru the ret_name pointer + a pointer to the string which is the entry name. + +*/ +int +dwarf_globname(Dwarf_Global glob, char **ret_name, Dwarf_Error * error) +{ + if (glob == NULL) { + _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); + return (DW_DLV_ERROR); + } + + *ret_name = (char *) (glob->gl_name); + return DW_DLV_OK; +} + + +/* + Given a pubnames entry (or other like section entry) + return thru the ret_off pointer the + global offset of the DIE for this entry. + The global offset is the offset within the .debug_info + section as a whole. +*/ +int +dwarf_global_die_offset(Dwarf_Global global, + Dwarf_Off * ret_off, Dwarf_Error * error) +{ + if (global == NULL) { + _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); + return (DW_DLV_ERROR); + } + + if (global->gl_context == NULL) { + _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); + return (DW_DLV_ERROR); + } + + *ret_off = (global->gl_named_die_offset_within_cu + + global->gl_context->pu_offset_of_cu_header); + return DW_DLV_OK; +} + +/* + Given a pubnames entry (or other like section entry) + return thru the ret_off pointer the + offset of the compilation unit header of the + compilation unit the global is part of. + + In early versions of this, the value returned was + the offset of the compilation unit die, and + other cu-local die offsets were faked so adding this to + such a cu-local offset got a true section offset. + Now things do as they say (adding *cu_header_offset to + a cu-local offset gets the section offset). + +*/ +int +dwarf_global_cu_offset(Dwarf_Global global, + Dwarf_Off * cu_header_offset, + Dwarf_Error * error) +{ + Dwarf_Global_Context con = 0; + + if (global == NULL) { + _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); + return (DW_DLV_ERROR); + } + + con = global->gl_context; + + if (con == NULL) { + _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); + return (DW_DLV_ERROR); + } + + /* In early libdwarf, this incorrectly returned the offset of the + CU DIE. Now correctly returns the header offset. */ + *cu_header_offset = con->pu_offset_of_cu_header; + + return DW_DLV_OK; +} + +/* + Give back the pubnames entry (or any other like section) + name, symbol DIE offset, and the cu-DIE offset. + + Various errors are possible. + + The string pointer returned thru ret_name is not + dwarf_get_alloc()ed, so no dwarf_dealloc() + DW_DLA_STRING should be applied to it. + +*/ +int +dwarf_global_name_offsets(Dwarf_Global global, + char **ret_name, + Dwarf_Off * die_offset, + Dwarf_Off * cu_die_offset, + Dwarf_Error * error) +{ + Dwarf_Global_Context con = 0; + Dwarf_Debug dbg = 0; + Dwarf_Off off = 0; + + if (global == NULL) { + _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); + return (DW_DLV_ERROR); + } + + con = global->gl_context; + + if (con == NULL) { + _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); + return (DW_DLV_ERROR); + } + + off = con->pu_offset_of_cu_header; + /* The offset had better not be too close to the end. If it is, + _dwarf_length_of_cu_header() will step off the end and therefore + must not be used. 10 is a meaningless heuristic, but no CU + header is that small so it is safe. An erroneous offset is due + to a bug in the tool chain. A bug like this has been seen on + IRIX with MIPSpro 7.3.1.3 and an executable > 2GB in size and + with 2 million pubnames entries. */ +#define MIN_CU_HDR_SIZE 10 + dbg = con->pu_dbg; + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + if (dbg->de_debug_info_size && + ((off + MIN_CU_HDR_SIZE) >= dbg->de_debug_info_size)) { + _dwarf_error(NULL, error, DW_DLE_OFFSET_BAD); + return (DW_DLV_ERROR); + } +#undef MIN_CU_HDR_SIZE + if (die_offset != NULL) { + *die_offset = global->gl_named_die_offset_within_cu + off; + } + + *ret_name = (char *) global->gl_name; + + if (cu_die_offset != NULL) { + int res = _dwarf_load_debug_info(dbg, error); + + if (res != DW_DLV_OK) { + return res; + } + /* The offset had better not be too close to the end. If it is, + _dwarf_length_of_cu_header() will step off the end and + therefore must not be used. 10 is a meaningless heuristic, + but no CU header is that small so it is safe. */ + if ((off + 10) >= dbg->de_debug_info_size) { + _dwarf_error(NULL, error, DW_DLE_OFFSET_BAD); + return (DW_DLV_ERROR); + } + *cu_die_offset = off + _dwarf_length_of_cu_header(dbg, off); + } + + + return DW_DLV_OK; +} + +/* + We have the offset to a CU header. + Return thru outFileOffset the offset of the CU DIE. + + New June, 2001. + Used by SGI debuggers. + No error is possible. +*/ + +/* ARGSUSED */ +int +dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg, + Dwarf_Off + in_cu_header_offset, + Dwarf_Off * + out_cu_die_offset, + Dwarf_Error * err) +{ + Dwarf_Off len = + _dwarf_length_of_cu_header(dbg, in_cu_header_offset); + + Dwarf_Off newoff = in_cu_header_offset + len; + + *out_cu_die_offset = newoff; + return DW_DLV_OK; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_global.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_global.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,124 @@ +/* + + Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + + +typedef struct Dwarf_Global_Context_s *Dwarf_Global_Context; + +/* + This struct contains header information for a set of pubnames. + Essentially, they contain the context for a set of pubnames + belonging to a compilation-unit. + + This is also used for the sgi-specific + weaknames, typenames, varnames, funcnames data: + the structs for those are incomplete and + instances of this are used instead. + + Also used for DWARF3 .debug_pubtypes. + +*/ +struct Dwarf_Global_Context_s { + + /* Length in .debug_pubnames (etc) of a set of names for a + compilation-unit. Dwarf_Word pu_length; The value is not made + available outside libdwarf and not used inside, so no need to + record it. */ + + /* For this context, size of a length. 4 or 8 */ + unsigned char pu_length_size; + + /* For this CU, size of the extension 0 except for dwarf2 extension + 64bit, in which case is 4. */ + unsigned char pu_extension_size; + + /* + Offset into .debug_info of the compilation-unit header (not DIE) + for this set of pubnames. */ + Dwarf_Off pu_offset_of_cu_header; + + /* Size of compilation-unit that these pubnames are in. */ + Dwarf_Unsigned pu_info_length; + + Dwarf_Debug pu_dbg; +}; + + +/* This struct contains information for a single pubname. */ +struct Dwarf_Global_s { + + /* + Offset from the start of the corresponding compilation-unit of + the DIE for the given pubname CU. */ + Dwarf_Off gl_named_die_offset_within_cu; + + /* Points to the given pubname. */ + Dwarf_Small *gl_name; + + /* Context for this pubname. */ + Dwarf_Global_Context gl_context; +}; + +int _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, + Dwarf_Small * + section_data_ptr, + Dwarf_Unsigned + section_length, + Dwarf_Global ** globals, + Dwarf_Signed * return_count, + Dwarf_Error * error, + int context_code, + int global_code, + int length_err_num, + int version_err_num); + +void +_dwarf_internal_globals_dealloc( Dwarf_Debug dbg, Dwarf_Global *dwgl, + Dwarf_Signed count, + int context_code, + int global_code, + int list_code); + + +#ifdef __sgi /* __sgi should only be defined for IRIX/MIPS. */ +void _dwarf_fix_up_offset_irix(Dwarf_Debug dbg, + Dwarf_Unsigned *varp, + char *caller_site_name); +#define FIX_UP_OFFSET_IRIX_BUG(ldbg,var,name) _dwarf_fix_up_offset_irix(ldbg,&var,name) +#else +#define FIX_UP_OFFSET_IRIX_BUG(ldbg,var,name) +#endif + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_incl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_incl.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,65 @@ +/* + + Copyright (C) 2000, 2002, 2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#ifndef DWARF_INCL_H +#define DWARF_INCL_H +#if (!defined(HAVE_RAW_LIBELF_OK) && defined(HAVE_LIBELF_OFF64_OK) ) +/* At a certain point libelf.h requires _GNU_SOURCE. + here we assume the criteria in configure determine that + usefully. +*/ +#define _GNU_SOURCE 1 +#endif + + +#include "libdwarfdefs.h" +#include + +#ifdef HAVE_ELF_H +#include +#endif + +#include +#include +#include + +#include "dwarf_base_types.h" +#include "dwarf_alloc.h" +#include "dwarf_opaque.h" +#include "dwarf_error.h" +#include "dwarf_util.h" +#endif /* DWARF_INCL_H */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_init_finish.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_init_finish.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,822 @@ +/* + + Copyright (C) 2000,2002,2003,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + +#if (!defined(HAVE_RAW_LIBELF_OK) && defined(HAVE_LIBELF_OFF64_OK) ) +#endif + +#include "config.h" +#include "dwarf_incl.h" +#ifdef HAVE_ELF_H +#include +#endif +#ifdef __SGI_FAST_LIBELF +#include +#else +#ifdef HAVE_LIBELF_H +#include +#else +#ifdef HAVE_LIBELF_LIBELF_H +#include +#endif +#endif +#endif /* !defined(__SGI_FAST_LIBELF) */ + +#include +#include +#include +#include +#include + +#include "dwarf_incl.h" +#include "malloc_check.h" + +#define DWARF_DBG_ERROR(dbg,errval,retval) \ + _dwarf_error(dbg, error, errval); return(retval); + +#define FALSE 0 +#define TRUE 1 + +#ifdef __SGI_FAST_LIBELF +#else +#ifdef HAVE_ELF64_GETEHDR +extern Elf64_Ehdr *elf64_getehdr(Elf *); +#endif +#ifdef HAVE_ELF64_GETSHDR +extern Elf64_Shdr *elf64_getshdr(Elf_Scn *); +#endif +#endif /* !defined(__SGI_FAST_LIBELF) */ + + +/* This static is copied to the dbg on dbg init + so that the static need not be referenced at + run time, preserving better locality of + reference. + Value is 0 means do the string check. + Value non-zero means do not do the check. +*/ +static Dwarf_Small _dwarf_assume_string_bad; + + +int +dwarf_set_stringcheck(int newval) +{ + int oldval = _dwarf_assume_string_bad; + + _dwarf_assume_string_bad = newval; + return oldval; +} + +#ifdef __SGI_FAST_LIBELF +/* + This function translates an elf_sgi error code into a libdwarf + code. + */ +static int +_dwarf_error_code_from_elf_sgi_error_code(enum elf_sgi_error_type val) +{ + switch (val) { + case ELF_SGI_ERROR_OK: + return DW_DLE_NE; + case ELF_SGI_ERROR_BAD_ALLOC: + return DW_DLE_MAF; + case ELF_SGI_ERROR_FORMAT: + return DW_DLE_MDE; + case ELF_SGI_ERROR_ERRNO: + return DW_DLE_IOF; + case ELF_SGI_ERROR_TOO_BIG: + return DW_DLE_MOF; + default: + return DW_DLE_LEE; + } +} +#endif + +/* + Given an Elf ptr, set up dbg with pointers + to all the Dwarf data sections. + Return NULL on error. + + This function is also responsible for determining + whether the given object contains Dwarf information + or not. The test currently used is that it contains + either a .debug_info or a .debug_frame section. If + not, it returns DW_DLV_NO_ENTRY causing dwarf_init() also to + return DW_DLV_NO_ENTRY. Earlier, we had thought of using only + the presence/absence of .debug_info to test, but we + added .debug_frame since there could be stripped objects + that have only a .debug_frame section for exception + processing. + DW_DLV_NO_ENTRY or DW_DLV_OK or DW_DLV_ERROR +*/ +static int +_dwarf_setup(Dwarf_Debug dbg, dwarf_elf_handle elf, Dwarf_Error * error) +{ +#ifdef __SGI_FAST_LIBELF + Elf64_Ehdr ehdr; + Elf64_Shdr shdr; + enum elf_sgi_error_type sres; + unsigned char const *ehdr_ident = 0; +#else + Elf32_Ehdr *ehdr32 = 0; + +#ifdef HAVE_ELF64_GETEHDR + Elf64_Ehdr *ehdr64 = 0; +#endif + Elf32_Shdr *shdr32 = 0; + +#ifdef HAVE_ELF64_GETSHDR + Elf64_Shdr *shdr64 = 0; +#endif + Elf_Scn *scn = 0; + char *ehdr_ident = 0; +#endif /* !defined(__SGI_FAST_LIBELF) */ + Dwarf_Half machine = 0; + char *scn_name = 0; + int is_64bit = 0; + int foundDwarf = 0; + + Dwarf_Unsigned section_size = 0; + Dwarf_Unsigned section_count = 0; + Dwarf_Half section_index = 0; + Dwarf_Addr section_addr = 0; + + foundDwarf = FALSE; + dbg->de_elf = elf; + + dbg->de_assume_string_in_bounds = _dwarf_assume_string_bad; + +#ifdef __SGI_FAST_LIBELF + sres = elf_sgi_ehdr(elf, &ehdr); + if (sres != ELF_SGI_ERROR_OK) { + DWARF_DBG_ERROR(dbg, + _dwarf_error_code_from_elf_sgi_error_code(sres), + DW_DLV_ERROR); + } + ehdr_ident = ehdr.e_ident; + section_count = ehdr.e_shnum; + machine = ehdr.e_machine; +#else + if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) { + DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETIDENT_ERROR, DW_DLV_ERROR); + } +#endif + + is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64); + + + dbg->de_same_endian = 1; + dbg->de_copy_word = memcpy; +#ifdef WORDS_BIGENDIAN + dbg->de_big_endian_object = 1; + if (ehdr_ident[EI_DATA] == ELFDATA2LSB) { + dbg->de_same_endian = 0; + dbg->de_big_endian_object = 0; + dbg->de_copy_word = _dwarf_memcpy_swap_bytes; + } +#else /* little endian */ + dbg->de_big_endian_object = 0; + if (ehdr_ident[EI_DATA] == ELFDATA2MSB) { + dbg->de_same_endian = 0; + dbg->de_big_endian_object = 1; + dbg->de_copy_word = _dwarf_memcpy_swap_bytes; + } +#endif /* !WORDS_BIGENDIAN */ + + /* The following de_length_size is Not Too Significant. Only used + one calculation, and an approximate one at that. */ + dbg->de_length_size = is_64bit ? 8 : 4; + dbg->de_pointer_size = is_64bit ? 8 : 4; + + +#ifdef __SGI_FAST_LIBELF + /* We've already loaded the ELF header, so there's nothing to do + here */ +#else +#ifdef HAVE_ELF64_GETEHDR + if (is_64bit) { + ehdr64 = elf64_getehdr(elf); + if (ehdr64 == NULL) { + DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETEHDR_ERROR, + DW_DLV_ERROR); + } + section_count = ehdr64->e_shnum; + machine = ehdr64->e_machine; + } else +#endif + { + ehdr32 = elf32_getehdr(elf); + if (ehdr32 == NULL) { + DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETEHDR_ERROR, + DW_DLV_ERROR); + } + section_count = ehdr32->e_shnum; + machine = ehdr32->e_machine; + } +#endif /* !defined(__SGI_FAST_LIBELF) */ + + if (is_64bit && machine != EM_MIPS) { + /* MIPS/IRIX makes pointer size and length size 8 for -64. + Other platforms make length 4 always. */ + /* 4 here supports 32bit-offset dwarf2, as emitted by cygnus + tools, and the dwarfv2.1 64bit extension setting. */ + dbg->de_length_size = 4; + } + + /* We start at index 1 to skip the initial empty section. */ + for (section_index = 1; section_index < section_count; + ++section_index) { + +#ifdef __SGI_FAST_LIBELF + sres = elf_sgi_shdr(elf, section_index, &shdr); + if (sres != ELF_SGI_ERROR_OK) { + DWARF_DBG_ERROR(dbg, + _dwarf_error_code_from_elf_sgi_error_code + (sres), DW_DLV_ERROR); + } + + section_size = shdr.sh_size; + section_addr = shdr.sh_addr; + + sres = + elf_sgi_string(elf, ehdr.e_shstrndx, shdr.sh_name, + (char const **) &scn_name); + if (sres != ELF_SGI_ERROR_OK) { + DWARF_DBG_ERROR(dbg, + _dwarf_error_code_from_elf_sgi_error_code + (sres), DW_DLV_ERROR); + } +#else /* !defined(__SGI_FAST_LIBELF) */ + scn = elf_getscn(elf, section_index); + if (scn == NULL) { + DWARF_DBG_ERROR(dbg, DW_DLE_MDE, DW_DLV_ERROR); + } +#ifdef HAVE_ELF64_GETSHDR + if (is_64bit) { + shdr64 = elf64_getshdr(scn); + if (shdr64 == NULL) { + DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETSHDR_ERROR, + DW_DLV_ERROR); + } + + section_size = shdr64->sh_size; + section_addr = shdr64->sh_addr; + + if ((scn_name = elf_strptr(elf, ehdr64->e_shstrndx, + shdr64->sh_name)) + == NULL) { + DWARF_DBG_ERROR(dbg, DW_DLE_ELF_STRPTR_ERROR, + DW_DLV_ERROR); + } + } else +#endif /* HAVE_ELF64_GETSHDR */ + { + if ((shdr32 = elf32_getshdr(scn)) == NULL) { + DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETSHDR_ERROR, 0); + } + + section_size = shdr32->sh_size; + section_addr = shdr32->sh_addr; + + if ((scn_name = elf_strptr(elf, ehdr32->e_shstrndx, + shdr32->sh_name)) == NULL) { + DWARF_DBG_ERROR(dbg, DW_DLE_ELF_STRPTR_ERROR, + DW_DLV_ERROR); + } + } +#endif /* !defined(__SGI_FAST_LIBELF) */ + + if (strncmp(scn_name, ".debug_", 7) + && strcmp(scn_name, ".eh_frame") + ) + continue; + + else if (strcmp(scn_name, ".debug_info") == 0) { + if (dbg->de_debug_info != NULL) { + DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_INFO_DUPLICATE, + DW_DLV_ERROR); + } + if (section_size == 0) { + /* Know no reason to allow empty debug_info section */ + DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_INFO_NULL, + DW_DLV_ERROR); + } + foundDwarf = TRUE; + dbg->de_debug_info_index = section_index; + dbg->de_debug_info_size = section_size; + } + + else if (strcmp(scn_name, ".debug_abbrev") == 0) { + if (dbg->de_debug_abbrev != NULL) { + DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_ABBREV_DUPLICATE, + DW_DLV_ERROR); + } + if (section_size == 0) { + /* Know no reason to allow empty debug_abbrev section */ + DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_ABBREV_NULL, + DW_DLV_ERROR); + } + dbg->de_debug_abbrev_index = section_index; + dbg->de_debug_abbrev_size = section_size; + } + + else if (strcmp(scn_name, ".debug_aranges") == 0) { + if (dbg->de_debug_aranges_index != 0) { + DWARF_DBG_ERROR(dbg, + DW_DLE_DEBUG_ARANGES_DUPLICATE, + DW_DLV_ERROR); + } + if (section_size == 0) { + /* a zero size section is just empty. Ok, no error */ + continue; + } + dbg->de_debug_aranges_index = section_index; + dbg->de_debug_aranges_size = section_size; + } + + else if (strcmp(scn_name, ".debug_line") == 0) { + if (dbg->de_debug_line_index != 0) { + DWARF_DBG_ERROR(dbg, + DW_DLE_DEBUG_LINE_DUPLICATE, + DW_DLV_ERROR); + } + if (section_size == 0) { + /* a zero size section is just empty. Ok, no error */ + continue; + } + dbg->de_debug_line_index = section_index; + dbg->de_debug_line_size = section_size; + } + + else if (strcmp(scn_name, ".debug_frame") == 0) { + if (dbg->de_debug_frame_index != 0) { + DWARF_DBG_ERROR(dbg, + DW_DLE_DEBUG_FRAME_DUPLICATE, + DW_DLV_ERROR); + } + if (section_size == 0) { + /* a zero size section is just empty. Ok, no error */ + continue; + } + dbg->de_debug_frame_index = section_index; + dbg->de_debug_frame_size = section_size; + foundDwarf = TRUE; + } else if (strcmp(scn_name, ".eh_frame") == 0) { + /* gnu egcs-1.1.2 data */ + if (dbg->de_debug_frame_eh_gnu_index != 0) { + DWARF_DBG_ERROR(dbg, + DW_DLE_DEBUG_FRAME_DUPLICATE, + DW_DLV_ERROR); + } + if (section_size == 0) { + /* a zero size section is just empty. Ok, no error */ + continue; + } + dbg->de_debug_frame_eh_gnu_index = section_index; + dbg->de_debug_frame_size_eh_gnu = section_size; + dbg->de_debug_frame_eh_addr = section_addr; + foundDwarf = TRUE; + } + + else if (strcmp(scn_name, ".debug_loc") == 0) { + if (dbg->de_debug_loc_index != 0) { + DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_LOC_DUPLICATE, + DW_DLV_ERROR); + } + if (section_size == 0) { + /* a zero size section is just empty. Ok, no error */ + continue; + } + dbg->de_debug_loc_index = section_index; + dbg->de_debug_loc_size = section_size; + } + + + else if (strcmp(scn_name, ".debug_pubnames") == 0) { + if (dbg->de_debug_pubnames_index != 0) { + DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_PUBNAMES_DUPLICATE, + DW_DLV_ERROR); + } + if (section_size == 0) { + /* a zero size section is just empty. Ok, no error */ + continue; + } + dbg->de_debug_pubnames_index = section_index; + dbg->de_debug_pubnames_size = section_size; + } + + else if (strcmp(scn_name, ".debug_str") == 0) { + if (dbg->de_debug_str_index != 0) { + DWARF_DBG_ERROR(dbg, + DW_DLE_DEBUG_STR_DUPLICATE, + DW_DLV_ERROR); + } + if (section_size == 0) { + /* a zero size section is just empty. Ok, no error */ + continue; + } + dbg->de_debug_str_index = section_index; + dbg->de_debug_str_size = section_size; + } + + else if (strcmp(scn_name, ".debug_funcnames") == 0) { + if (dbg->de_debug_funcnames_index != 0) { + DWARF_DBG_ERROR(dbg, + DW_DLE_DEBUG_FUNCNAMES_DUPLICATE, + DW_DLV_ERROR); + } + if (section_size == 0) { + /* a zero size section is just empty. Ok, no error */ + continue; + } + dbg->de_debug_funcnames_index = section_index; + dbg->de_debug_funcnames_size = section_size; + } + + else if (strcmp(scn_name, ".debug_typenames") == 0) { + /* SGI IRIX-only, created years before DWARF3. Content + essentially identical to .debug_pubtypes. */ + if (dbg->de_debug_typenames_index != 0) { + DWARF_DBG_ERROR(dbg, + DW_DLE_DEBUG_TYPENAMES_DUPLICATE, + DW_DLV_ERROR); + } + if (section_size == 0) { + /* a zero size section is just empty. Ok, no error */ + continue; + } + dbg->de_debug_typenames_index = section_index; + dbg->de_debug_typenames_size = section_size; + } else if (strcmp(scn_name, ".debug_pubtypes") == 0) { + /* Section new in DWARF3. */ + if (dbg->de_debug_pubtypes_index != 0) { + DWARF_DBG_ERROR(dbg, + DW_DLE_DEBUG_PUBTYPES_DUPLICATE, + DW_DLV_ERROR); + } + if (section_size == 0) { + /* a zero size section is just empty. Ok, no error */ + continue; + } + dbg->de_debug_pubtypes_index = section_index; + dbg->de_debug_pubtypes_size = section_size; + } + + else if (strcmp(scn_name, ".debug_varnames") == 0) { + if (dbg->de_debug_varnames_index != 0) { + DWARF_DBG_ERROR(dbg, + DW_DLE_DEBUG_VARNAMES_DUPLICATE, + DW_DLV_ERROR); + } + if (section_size == 0) { + /* a zero size section is just empty. Ok, no error */ + continue; + } + dbg->de_debug_varnames_index = section_index; + dbg->de_debug_varnames_size = section_size; + } + + else if (strcmp(scn_name, ".debug_weaknames") == 0) { + if (dbg->de_debug_weaknames_index != 0) { + DWARF_DBG_ERROR(dbg, + DW_DLE_DEBUG_WEAKNAMES_DUPLICATE, + DW_DLV_ERROR); + } + if (section_size == 0) { + /* a zero size section is just empty. Ok, no error */ + continue; + } + dbg->de_debug_weaknames_index = section_index; + dbg->de_debug_weaknames_size = section_size; + } else if (strcmp(scn_name, ".debug_macinfo") == 0) { + if (dbg->de_debug_macinfo_index != 0) { + DWARF_DBG_ERROR(dbg, + DW_DLE_DEBUG_MACINFO_DUPLICATE, + DW_DLV_ERROR); + } + if (section_size == 0) { + /* a zero size section is just empty. Ok, no error */ + continue; + } + dbg->de_debug_macinfo_index = section_index; + dbg->de_debug_macinfo_size = section_size; + } + } + if (foundDwarf) { + return DW_DLV_OK; + } + + return (DW_DLV_NO_ENTRY); +} + + +/* + The basic dwarf initializer function for consumers. + Return NULL on error. +*/ +int +dwarf_init(int fd, + Dwarf_Unsigned access, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, Dwarf_Error * error) +{ + Dwarf_Debug dbg; + struct stat fstat_buf; + dwarf_elf_handle elf; + int res; + +#ifdef __SGI_FAST_LIBELF + enum elf_sgi_error_type sres; +#else + Elf_Cmd what_kind_of_elf_read; +#endif + + dbg = _dwarf_get_debug(); + if (dbg == NULL) { + DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); + } + dbg->de_errhand = errhand; + dbg->de_errarg = errarg; + dbg->de_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE; + dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM; + + + if (fstat(fd, &fstat_buf) != 0) { + DWARF_DBG_ERROR(dbg, DW_DLE_FSTAT_ERROR, DW_DLV_ERROR); + } + if (!S_ISREG(fstat_buf.st_mode)) { + DWARF_DBG_ERROR(dbg, DW_DLE_FSTAT_MODE_ERROR, DW_DLV_ERROR); + } + + if (access != DW_DLC_READ) { + DWARF_DBG_ERROR(dbg, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR); + } + dbg->de_access = access; + +#ifdef __SGI_FAST_LIBELF + elf = elf_sgi_new(); + if (elf == NULL) { + DWARF_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_ERROR); + } + + sres = elf_sgi_begin_fd(elf, fd, 0); + if (sres != ELF_SGI_ERROR_OK) { + elf_sgi_free(elf); + DWARF_DBG_ERROR(dbg, + _dwarf_error_code_from_elf_sgi_error_code(sres), + DW_DLV_ERROR); + } +#else /* ! __SGI_FAST_LIBELF */ + elf_version(EV_CURRENT); + /* changed to mmap request per bug 281217. 6/95 */ +#ifdef HAVE_ELF_C_READ_MMAP + /* ELF_C_READ_MMAP is an SGI IRIX specific enum value from IRIX + libelf.h meaning read but use mmap */ + what_kind_of_elf_read = ELF_C_READ_MMAP; +#else /* !HAVE_ELF_C_READ_MMAP */ + /* ELF_C_READ is a portable value */ + what_kind_of_elf_read = ELF_C_READ; +#endif /* HAVE_ELF_C_READ_MMAP */ + + if ((elf = elf_begin(fd, what_kind_of_elf_read, 0)) == NULL) { + DWARF_DBG_ERROR(dbg, DW_DLE_ELF_BEGIN_ERROR, DW_DLV_ERROR); + } +#endif /* !defined(__SGI_FAST_LIBELF) */ + + dbg->de_elf_must_close = 1; + if ((res = _dwarf_setup(dbg, elf, error)) != DW_DLV_OK) { +#ifdef __SGI_FAST_LIBELF + elf_sgi_free(elf); +#else + elf_end(elf); +#endif + free(dbg); + return (res); + } + + /* call cannot fail: no malloc or free involved */ + _dwarf_setup_debug(dbg); + + *ret_dbg = dbg; + return (DW_DLV_OK); +} + + +/* + The alternate dwarf setup call for consumers +*/ +int +dwarf_elf_init(dwarf_elf_handle elf_file_pointer, + Dwarf_Unsigned access, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, + Dwarf_Debug * ret_dbg, Dwarf_Error * error) +{ + Dwarf_Debug dbg; + int res; + + dbg = _dwarf_get_debug(); + if (dbg == NULL) { + DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); + } + dbg->de_errhand = errhand; + dbg->de_errarg = errarg; + dbg->de_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE; + dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM; + + if (access != DW_DLC_READ) { + DWARF_DBG_ERROR(dbg, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR); + } + dbg->de_access = access; + + dbg->de_elf_must_close = 0; + if ((res = _dwarf_setup(dbg, elf_file_pointer, error)) != DW_DLV_OK) { + free(dbg); + return (res); + } + + /* this call cannot fail: allocates nothing, releases nothing */ + _dwarf_setup_debug(dbg); + + *ret_dbg = dbg; + return (DW_DLV_OK); +} + + +/* + Frees all memory that was not previously freed + by dwarf_dealloc. + Aside from certain categories. +*/ +int +dwarf_finish(Dwarf_Debug dbg, Dwarf_Error * error) +{ + int res = DW_DLV_OK; + + if (dbg->de_elf_must_close) { + /* Must do this *before* _dwarf_free_all_of_one_debug() as that + zeroes out dbg contents */ +#ifdef __SGI_FAST_LIBELF + elf_sgi_free(dbg->de_elf); +#else + elf_end(dbg->de_elf); +#endif + } + + res = _dwarf_free_all_of_one_debug(dbg); + if (res == DW_DLV_ERROR) { + DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); + } + dwarf_malloc_check_complete("After Final free"); + + return res; + + +} + + +/* + This function returns the Elf * pointer + associated with a Dwarf_Debug. +*/ +int +dwarf_get_elf(Dwarf_Debug dbg, dwarf_elf_handle * elf, + Dwarf_Error * error) +{ + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + + *elf = dbg->de_elf; + return (DW_DLV_OK); +} + + +/* + Load the ELF section with the specified index and set the + pointer pointed to by section_data to the memory where it + was loaded. + */ +int +_dwarf_load_section(Dwarf_Debug dbg, + Dwarf_Half section_index, + Dwarf_Small ** section_data, Dwarf_Error * error) +{ + if (section_index == 0) { + return DW_DLV_NO_ENTRY; + } + + /* check to see if the section is already loaded */ + if (*section_data != NULL) { + return DW_DLV_OK; + } + + { +#ifdef __SGI_FAST_LIBELF + enum elf_sgi_error_type sres; + + sres = elf_sgi_section(dbg->de_elf, + section_index, (void **) section_data); + if (sres != ELF_SGI_ERROR_OK) { + DWARF_DBG_ERROR(dbg, + _dwarf_error_code_from_elf_sgi_error_code + (sres), DW_DLV_ERROR); + } +#else + Elf_Scn *scn; + Elf_Data *data; + + scn = elf_getscn(dbg->de_elf, section_index); + if (scn == NULL) { + _dwarf_error(dbg, error, DW_DLE_MDE); + return DW_DLV_ERROR; + } + + /* + When using libelf as a producer, section data may be stored + in multiple buffers. In libdwarf however, we only use libelf + as a consumer (there is a dwarf producer API, but it doesn't + use libelf). Because of this, this single call to elf_getdata + will retrieve the entire section in a single contiguous + buffer. */ + data = elf_getdata(scn, NULL); + if (data == NULL) { + _dwarf_error(dbg, error, DW_DLE_MDE); + return DW_DLV_ERROR; + } + + *section_data = data->d_buf; +#endif /* !defined(__SGI_FAST_LIBELF) */ + } + + return DW_DLV_OK; +} + +/* This is a hack so clients can verify offsets. + Added April 2005 so that debugger can detect broken offsets + (which happened in an IRIX -64 executable larger than 2GB + using MIPSpro 7.3.1.3 compilers. A couple .debug_pubnames + offsets were wrong.). +*/ +int +dwarf_get_section_max_offsets(Dwarf_Debug dbg, + Dwarf_Unsigned * debug_info_size, + Dwarf_Unsigned * debug_abbrev_size, + Dwarf_Unsigned * debug_line_size, + Dwarf_Unsigned * debug_loc_size, + Dwarf_Unsigned * debug_aranges_size, + Dwarf_Unsigned * debug_macinfo_size, + Dwarf_Unsigned * debug_pubnames_size, + Dwarf_Unsigned * debug_str_size, + Dwarf_Unsigned * debug_frame_size, + Dwarf_Unsigned * debug_ranges_size, + Dwarf_Unsigned * debug_typenames_size) +{ + *debug_info_size = dbg->de_debug_info_size; + *debug_abbrev_size = dbg->de_debug_abbrev_size; + *debug_line_size = dbg->de_debug_line_size; + *debug_loc_size = dbg->de_debug_loc_size; + *debug_aranges_size = dbg->de_debug_aranges_size; + *debug_macinfo_size = dbg->de_debug_macinfo_size; + *debug_pubnames_size = dbg->de_debug_pubnames_size; + *debug_str_size = dbg->de_debug_str_size; + *debug_frame_size = dbg->de_debug_frame_size; + *debug_ranges_size = 0; /* Not yet supported. */ + *debug_typenames_size = dbg->de_debug_typenames_size; + + + return DW_DLV_OK; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_leb.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_leb.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,149 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include + + +/* + decode ULEB +*/ +Dwarf_Unsigned +_dwarf_decode_u_leb128(Dwarf_Small * leb128, Dwarf_Word * leb128_length) +{ + unsigned char byte; + Dwarf_Word word_number; + Dwarf_Unsigned number; + Dwarf_Sword shift; + Dwarf_Sword byte_length; + + /* The following unrolls-the-loop for the first few bytes and + unpacks into 32 bits to make this as fast as possible. + word_number is assumed big enough that the shift has a defined + result. */ + if ((*leb128 & 0x80) == 0) { + if (leb128_length != NULL) + *leb128_length = 1; + return (*leb128); + } else if ((*(leb128 + 1) & 0x80) == 0) { + if (leb128_length != NULL) + *leb128_length = 2; + + word_number = *leb128 & 0x7f; + word_number |= (*(leb128 + 1) & 0x7f) << 7; + return (word_number); + } else if ((*(leb128 + 2) & 0x80) == 0) { + if (leb128_length != NULL) + *leb128_length = 3; + + word_number = *leb128 & 0x7f; + word_number |= (*(leb128 + 1) & 0x7f) << 7; + word_number |= (*(leb128 + 2) & 0x7f) << 14; + return (word_number); + } else if ((*(leb128 + 3) & 0x80) == 0) { + if (leb128_length != NULL) + *leb128_length = 4; + + word_number = *leb128 & 0x7f; + word_number |= (*(leb128 + 1) & 0x7f) << 7; + word_number |= (*(leb128 + 2) & 0x7f) << 14; + word_number |= (*(leb128 + 3) & 0x7f) << 21; + return (word_number); + } + + /* The rest handles long numbers Because the 'number' may be larger + than the default int/unsigned, we must cast the 'byte' before + the shift for the shift to have a defined result. */ + number = 0; + shift = 0; + byte_length = 1; + byte = *(leb128); + for (;;) { + number |= ((Dwarf_Unsigned) (byte & 0x7f)) << shift; + + if ((byte & 0x80) == 0) { + if (leb128_length != NULL) + *leb128_length = byte_length; + return (number); + } + shift += 7; + + byte_length++; + ++leb128; + byte = *leb128; + } +} + +#define BITSINBYTE 8 + +/* + decode SLEB +*/ +Dwarf_Signed +_dwarf_decode_s_leb128(Dwarf_Small * leb128, Dwarf_Word * leb128_length) +{ + Dwarf_Signed number = 0; + Dwarf_Bool sign = 0; + Dwarf_Sword shift = 0; + unsigned char byte = *leb128; + Dwarf_Sword byte_length = 1; + + /* byte_length being the number of bytes of data absorbed so far in + turning the leb into a Dwarf_Signed. */ + + for (;;) { + sign = byte & 0x40; + number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift; + shift += 7; + + if ((byte & 0x80) == 0) { + break; + } + ++leb128; + byte = *leb128; + byte_length++; + } + + if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) { + number |= -((Dwarf_Signed) 1 << shift); + } + + if (leb128_length != NULL) + *leb128_length = byte_length; + return (number); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_line.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_line.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1827 @@ +/* + + Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include +#include "dwarf_line.h" +#ifdef HAVE_ALLOCA_H +#include +#endif + + +/* + Although source files is supposed to return the + source files in the compilation-unit, it does + not look for any in the statement program. In + other words, it ignores those defined using the + extended opcode DW_LNE_define_file. +*/ +int +dwarf_srcfiles(Dwarf_Die die, + char ***srcfiles, + Dwarf_Signed * srcfilecount, Dwarf_Error * error) +{ + /* + This pointer is used to scan the portion of the .debug_line + section for the current cu. */ + Dwarf_Small *line_ptr; + + + /* + Pointer to a DW_AT_stmt_list attribute in case it exists in the + die. */ + Dwarf_Attribute stmt_list_attr; + + /* Pointer to DW_AT_comp_dir attribute in die. */ + Dwarf_Attribute comp_dir_attr; + + /* Pointer to name of compilation directory. */ + Dwarf_Small *comp_dir = 0; + + /* Offset into .debug_line specified by a DW_AT_stmt_list + attribute. */ + Dwarf_Unsigned line_offset = 0; + + + + /* + This points to a block of char *'s, each of which points to a + file name. */ + char **ret_files = 0; + + /* The Dwarf_Debug this die belongs to. */ + Dwarf_Debug dbg = 0; + + /* Used to chain the file names. */ + Dwarf_Chain curr_chain = NULL; + Dwarf_Chain prev_chain = NULL; + Dwarf_Chain head_chain = NULL; + int resattr = 0; + int lres = 0; + struct Line_Table_Prefix_s line_prefix; + int i = 0; + int res = 0; + + + /* ***** BEGIN CODE ***** */ + + /* Reset error. */ + if (error != NULL) + *error = NULL; + + CHECK_DIE(die, DW_DLV_ERROR); + dbg = die->di_cu_context->cc_dbg; + + resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error); + if (resattr != DW_DLV_OK) { + return resattr; + } + + if (dbg->de_debug_line_index == 0) { + _dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_NULL); + return (DW_DLV_ERROR); + } + + res = + _dwarf_load_section(dbg, + dbg->de_debug_line_index, + &dbg->de_debug_line, error); + if (res != DW_DLV_OK) { + return res; + } + + lres = dwarf_formudata(stmt_list_attr, &line_offset, error); + if (lres != DW_DLV_OK) { + return lres; + } + if (line_offset >= dbg->de_debug_line_size) { + _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); + return (DW_DLV_ERROR); + } + line_ptr = dbg->de_debug_line + line_offset; + dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); + + /* + If die has DW_AT_comp_dir attribute, get the string that names + the compilation directory. */ + resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error); + if (resattr == DW_DLV_ERROR) { + return resattr; + } + if (resattr == DW_DLV_OK) { + int cres; + char *cdir; + + cres = dwarf_formstring(comp_dir_attr, &cdir, error); + if (cres == DW_DLV_ERROR) { + return cres; + } else if (cres == DW_DLV_OK) { + comp_dir = (Dwarf_Small *) cdir; + } + } + if (resattr == DW_DLV_OK) { + dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR); + } + dwarf_init_line_table_prefix(&line_prefix); + { + Dwarf_Small *line_ptr_out = 0; + int dres = dwarf_read_line_table_prefix(dbg, + line_ptr, + dbg->de_debug_line_size, + &line_ptr_out, + &line_prefix, error); + + if (dres == DW_DLV_ERROR) { + dwarf_free_line_table_prefix(&line_prefix); + return dres; + } + if (dres == DW_DLV_NO_ENTRY) { + dwarf_free_line_table_prefix(&line_prefix); + return dres; + } + + line_ptr = line_ptr_out; + } + + for (i = 0; i < line_prefix.pf_files_count; ++i) { + struct Line_Table_File_Entry_s *fe = + line_prefix.pf_line_table_file_entries + i; + char *file_name = (char *) fe->lte_filename; + char *dir_name = 0; + char *full_name = 0; + Dwarf_Unsigned dir_index = fe->lte_directory_index; + + if (dir_index == 0) { + dir_name = (char *) comp_dir; + } else { + dir_name = + (char *) line_prefix.pf_include_directories[fe-> + lte_directory_index + - 1]; + } + + /* dir_name can be NULL if there is no DW_AT_comp_dir */ + if ((*file_name) == '/' || dir_name == 0) { + /* This is safe because dwarf_dealloc is careful to not + dealloc strings which are part of the raw .debug_* data. + */ + full_name = file_name; + } else { + full_name = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING, + strlen(dir_name) + 1 + + strlen(file_name) + + 1); + if (full_name == NULL) { + dwarf_free_line_table_prefix(&line_prefix); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + /* This is not careful to avoid // in the output, Nothing + forces a 'canonical' name format here. Unclear if this + needs to be fixed. */ + strcpy(full_name, dir_name); + strcat(full_name, "/"); + strcat(full_name, file_name); + } + curr_chain = + (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (curr_chain == NULL) { + dwarf_free_line_table_prefix(&line_prefix); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + curr_chain->ch_item = full_name; + if (head_chain == NULL) + head_chain = prev_chain = curr_chain; + else { + prev_chain->ch_next = curr_chain; + prev_chain = curr_chain; + } + + + } + + curr_chain = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (curr_chain == NULL) { + dwarf_free_line_table_prefix(&line_prefix); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + + + + if (line_prefix.pf_files_count == 0) { + *srcfiles = NULL; + *srcfilecount = 0; + dwarf_free_line_table_prefix(&line_prefix); + return (DW_DLV_NO_ENTRY); + } + + ret_files = (char **) + _dwarf_get_alloc(dbg, DW_DLA_LIST, line_prefix.pf_files_count); + if (ret_files == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + dwarf_free_line_table_prefix(&line_prefix); + return (DW_DLV_ERROR); + } + + curr_chain = head_chain; + for (i = 0; i < line_prefix.pf_files_count; i++) { + *(ret_files + i) = curr_chain->ch_item; + prev_chain = curr_chain; + curr_chain = curr_chain->ch_next; + dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); + } + + *srcfiles = ret_files; + *srcfilecount = line_prefix.pf_files_count; + dwarf_free_line_table_prefix(&line_prefix); + return (DW_DLV_OK); +} + + +/* + return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR +*/ +int +_dwarf_internal_srclines(Dwarf_Die die, + Dwarf_Line ** linebuf, + Dwarf_Signed * count, + Dwarf_Bool doaddrs, + Dwarf_Bool dolines, Dwarf_Error * error) +{ + /* + This pointer is used to scan the portion of the .debug_line + section for the current cu. */ + Dwarf_Small *line_ptr = 0; + + /* + This points to the last byte of the .debug_line portion for the + current cu. */ + Dwarf_Small *line_ptr_end = 0; + + + /* + Pointer to a DW_AT_stmt_list attribute in case it exists in the + die. */ + Dwarf_Attribute stmt_list_attr = 0; + + /* Pointer to DW_AT_comp_dir attribute in die. */ + Dwarf_Attribute comp_dir_attr = 0; + + /* Pointer to name of compilation directory. */ + Dwarf_Small *comp_dir = NULL; + + /* + Offset into .debug_line specified by a DW_AT_stmt_list + attribute. */ + Dwarf_Unsigned line_offset = 0; + + Dwarf_File_Entry file_entries = 0; + + /* These are the state machine state variables. */ + Dwarf_Addr address = 0; + Dwarf_Word file = 1; + Dwarf_Word line = 1; + Dwarf_Word column = 0; + + /* phony init. See below for true initialization. */ + Dwarf_Bool is_stmt = false; + + Dwarf_Bool basic_block = false; + Dwarf_Bool prologue_end = false; + Dwarf_Bool epilogue_begin = false; + Dwarf_Small isa = 0; + Dwarf_Bool end_sequence = false; + + /* + These pointers are used to build the list of files names by this + cu. cur_file_entry points to the file name being added, and + prev_file_entry to the previous one. */ + Dwarf_File_Entry cur_file_entry, prev_file_entry; + + Dwarf_Sword i = 0; + Dwarf_Sword file_entry_count = 0; + + /* + This is the current opcode read from the statement program. */ + Dwarf_Small opcode = 0; + + /* + Pointer to a Dwarf_Line_Context_s structure that contains the + context such as file names and include directories for the set + of lines being generated. */ + Dwarf_Line_Context line_context = 0; + + /* + This is a pointer to the current line being added to the line + matrix. */ + Dwarf_Line curr_line = 0; + + /* + These variables are used to decode leb128 numbers. Leb128_num + holds the decoded number, and leb128_length is its length in + bytes. */ + Dwarf_Word leb128_num = 0; + Dwarf_Word leb128_length = 0; + Dwarf_Sword advance_line = 0; + + /* + This is the operand of the latest fixed_advance_pc extended + opcode. */ + Dwarf_Half fixed_advance_pc = 0; + + /* + Counts the number of lines in the line matrix. */ + Dwarf_Sword line_count = 0; + + /* This is the length of an extended opcode instr. */ + Dwarf_Word instr_length = 0; + Dwarf_Small ext_opcode = 0; + struct Line_Table_Prefix_s prefix; + + /* + Used to chain together pointers to line table entries that are + later used to create a block of Dwarf_Line entries. */ + Dwarf_Chain chain_line = NULL; + Dwarf_Chain head_chain = NULL; + Dwarf_Chain curr_chain = NULL; + + /* + This points to a block of Dwarf_Lines, a pointer to which is + returned in linebuf. */ + Dwarf_Line *block_line = 0; + + /* The Dwarf_Debug this die belongs to. */ + Dwarf_Debug dbg = 0; + int resattr = 0; + int lres = 0; + + int res = 0; + + /* ***** BEGIN CODE ***** */ + + if (error != NULL) + *error = NULL; + + CHECK_DIE(die, DW_DLV_ERROR); + dbg = die->di_cu_context->cc_dbg; + + res = + _dwarf_load_section(dbg, + dbg->de_debug_line_index, + &dbg->de_debug_line, error); + if (res != DW_DLV_OK) { + return res; + } + + resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error); + if (resattr != DW_DLV_OK) { + return resattr; + } + + + + lres = dwarf_formudata(stmt_list_attr, &line_offset, error); + if (lres != DW_DLV_OK) { + return lres; + } + + if (line_offset >= dbg->de_debug_line_size) { + _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); + return (DW_DLV_ERROR); + } + line_ptr = dbg->de_debug_line + line_offset; + dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); + + /* + If die has DW_AT_comp_dir attribute, get the string that names + the compilation directory. */ + resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error); + if (resattr == DW_DLV_ERROR) { + return resattr; + } + if (resattr == DW_DLV_OK) { + int cres; + char *cdir; + + cres = dwarf_formstring(comp_dir_attr, &cdir, error); + if (cres == DW_DLV_ERROR) { + return cres; + } else if (cres == DW_DLV_OK) { + comp_dir = (Dwarf_Small *) cdir; + } + } + if (resattr == DW_DLV_OK) { + dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR); + } + dwarf_init_line_table_prefix(&prefix); + + { + Dwarf_Small *newlinep = 0; + int res = dwarf_read_line_table_prefix(dbg, + line_ptr, + dbg->de_debug_line_size, + &newlinep, + &prefix, + error); + + if (res == DW_DLV_ERROR) { + dwarf_free_line_table_prefix(&prefix); + return res; + } + if (res == DW_DLV_NO_ENTRY) { + dwarf_free_line_table_prefix(&prefix); + return res; + } + line_ptr_end = prefix.pf_line_ptr_end; + line_ptr = newlinep; + } + + + /* Set up context structure for this set of lines. */ + line_context = (Dwarf_Line_Context) + _dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1); + if (line_context == NULL) { + dwarf_free_line_table_prefix(&prefix); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + /* Fill out a Dwarf_File_Entry list as we use that to implement the + define_file operation. */ + file_entries = prev_file_entry = NULL; + for (i = 0; i < prefix.pf_files_count; ++i) { + struct Line_Table_File_Entry_s *pfxfile = + prefix.pf_line_table_file_entries + i; + + cur_file_entry = (Dwarf_File_Entry) + _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1); + if (cur_file_entry == NULL) { + dwarf_free_line_table_prefix(&prefix); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + cur_file_entry->fi_file_name = pfxfile->lte_filename; + cur_file_entry->fi_dir_index = pfxfile->lte_directory_index; + cur_file_entry->fi_time_last_mod = + pfxfile->lte_last_modification_time; + + cur_file_entry->fi_file_length = pfxfile->lte_length_of_file; + + if (file_entries == NULL) + file_entries = cur_file_entry; + else + prev_file_entry->fi_next = cur_file_entry; + prev_file_entry = cur_file_entry; + + file_entry_count++; + } + + + /* Initialize the one state machine variable that depends on the + prefix. */ + is_stmt = prefix.pf_default_is_stmt; + + + /* Start of statement program. */ + while (line_ptr < line_ptr_end) { + int type; + + opcode = *(Dwarf_Small *) line_ptr; + line_ptr++; + + + /* 'type' is the output */ + WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base, + prefix.pf_opcode_length_table, line_ptr, + prefix.pf_std_op_count); + + if (type == LOP_DISCARD) { + int oc; + int opcnt = prefix.pf_opcode_length_table[opcode]; + + for (oc = 0; oc < opcnt; oc++) { + /* + ** Read and discard operands we don't + ** understand. + ** arbitrary choice of unsigned read. + ** signed read would work as well. + */ + Dwarf_Unsigned utmp2; + + DECODE_LEB128_UWORD(line_ptr, utmp2); + } + } else if (type == LOP_SPECIAL) { + /* This op code is a special op in the object, no matter + that it might fall into the standard op range in this + compile. That is, these are special opcodes between + opcode_base and MAX_LINE_OP_CODE. (including + opcode_base and MAX_LINE_OP_CODE) */ + + opcode = opcode - prefix.pf_opcode_base; + address = address + prefix.pf_minimum_instruction_length * + (opcode / prefix.pf_line_range); + line = + line + prefix.pf_line_base + + opcode % prefix.pf_line_range; + + if (dolines) { + curr_line = + (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1); + if (curr_line == NULL) { + dwarf_free_line_table_prefix(&prefix); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + curr_line->li_address = address; + curr_line->li_addr_line.li_l_data.li_file = + (Dwarf_Sword) file; + curr_line->li_addr_line.li_l_data.li_line = + (Dwarf_Sword) line; + curr_line->li_addr_line.li_l_data.li_column = + (Dwarf_Half) column; + curr_line->li_addr_line.li_l_data.li_is_stmt = is_stmt; + curr_line->li_addr_line.li_l_data.li_basic_block = + basic_block; + curr_line->li_addr_line.li_l_data.li_end_sequence = + curr_line->li_addr_line.li_l_data. + li_epilogue_begin = epilogue_begin; + curr_line->li_addr_line.li_l_data.li_prologue_end = + prologue_end; + curr_line->li_addr_line.li_l_data.li_isa = isa; + curr_line->li_context = line_context; + line_count++; + + chain_line = (Dwarf_Chain) + _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (chain_line == NULL) { + dwarf_free_line_table_prefix(&prefix); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + chain_line->ch_item = curr_line; + + if (head_chain == NULL) + head_chain = curr_chain = chain_line; + else { + curr_chain->ch_next = chain_line; + curr_chain = chain_line; + } + } + + basic_block = false; + } else if (type == LOP_STANDARD) { + switch (opcode) { + + case DW_LNS_copy:{ + if (dolines) { + + curr_line = + (Dwarf_Line) _dwarf_get_alloc(dbg, + DW_DLA_LINE, + 1); + if (curr_line == NULL) { + dwarf_free_line_table_prefix(&prefix); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + curr_line->li_address = address; + curr_line->li_addr_line.li_l_data.li_file = + (Dwarf_Sword) file; + curr_line->li_addr_line.li_l_data.li_line = + (Dwarf_Sword) line; + curr_line->li_addr_line.li_l_data.li_column = + (Dwarf_Half) column; + curr_line->li_addr_line.li_l_data.li_is_stmt = + is_stmt; + curr_line->li_addr_line.li_l_data. + li_basic_block = basic_block; + curr_line->li_addr_line.li_l_data. + li_end_sequence = end_sequence; + curr_line->li_context = line_context; + curr_line->li_addr_line.li_l_data. + li_epilogue_begin = epilogue_begin; + curr_line->li_addr_line.li_l_data. + li_prologue_end = prologue_end; + curr_line->li_addr_line.li_l_data.li_isa = isa; + line_count++; + + chain_line = (Dwarf_Chain) + _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (chain_line == NULL) { + dwarf_free_line_table_prefix(&prefix); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + chain_line->ch_item = curr_line; + if (head_chain == NULL) + head_chain = curr_chain = chain_line; + else { + curr_chain->ch_next = chain_line; + curr_chain = chain_line; + } + } + + basic_block = false; + prologue_end = false; + epilogue_begin = false; + break; + } + + case DW_LNS_advance_pc:{ + Dwarf_Unsigned utmp2; + + DECODE_LEB128_UWORD(line_ptr, utmp2); + leb128_num = (Dwarf_Word) utmp2; + address = + address + + prefix.pf_minimum_instruction_length * + leb128_num; + break; + } + + case DW_LNS_advance_line:{ + Dwarf_Signed stmp; + + DECODE_LEB128_SWORD(line_ptr, stmp); + advance_line = (Dwarf_Sword) stmp; + line = line + advance_line; + break; + } + + case DW_LNS_set_file:{ + Dwarf_Unsigned utmp2; + + DECODE_LEB128_UWORD(line_ptr, utmp2); + file = (Dwarf_Word) utmp2; + break; + } + + case DW_LNS_set_column:{ + Dwarf_Unsigned utmp2; + + DECODE_LEB128_UWORD(line_ptr, utmp2); + column = (Dwarf_Word) utmp2; + break; + } + + case DW_LNS_negate_stmt:{ + + is_stmt = !is_stmt; + break; + } + + case DW_LNS_set_basic_block:{ + + basic_block = true; + break; + } + + case DW_LNS_const_add_pc:{ + opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base; + address = + address + + prefix.pf_minimum_instruction_length * (opcode / + prefix. + pf_line_range); + + break; + } + + case DW_LNS_fixed_advance_pc:{ + + READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half, + line_ptr, sizeof(Dwarf_Half)); + line_ptr += sizeof(Dwarf_Half); + address = address + fixed_advance_pc; + break; + } + + /* New in DWARF3 */ + case DW_LNS_set_prologue_end:{ + + prologue_end = true; + break; + + + } + /* New in DWARF3 */ + case DW_LNS_set_epilogue_begin:{ + epilogue_begin = true; + break; + } + + /* New in DWARF3 */ + case DW_LNS_set_isa:{ + Dwarf_Unsigned utmp2; + + DECODE_LEB128_UWORD(line_ptr, utmp2); + isa = utmp2; + if (isa != utmp2) { + /* The value of the isa did not fit in our + local so we record it wrong. declare an + error. */ + dwarf_free_line_table_prefix(&prefix); + + _dwarf_error(dbg, error, + DW_DLE_LINE_NUM_OPERANDS_BAD); + return (DW_DLV_ERROR); + } + break; + } + } + + } else if (type == LOP_EXTENDED) { + Dwarf_Unsigned utmp3; + + DECODE_LEB128_UWORD(line_ptr, utmp3); + instr_length = (Dwarf_Word) utmp3; + /* Dwarf_Small is a ubyte and the extended opcode is a + ubyte, though not stated as clearly in the 2.0.0 spec as + one might hope. */ + ext_opcode = *(Dwarf_Small *) line_ptr; + line_ptr++; + switch (ext_opcode) { + + case DW_LNE_end_sequence:{ + end_sequence = true; + + if (dolines) { + curr_line = (Dwarf_Line) + _dwarf_get_alloc(dbg, DW_DLA_LINE, 1); + if (curr_line == NULL) { + dwarf_free_line_table_prefix(&prefix); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + curr_line->li_address = address; + curr_line->li_addr_line.li_l_data.li_file = + (Dwarf_Sword) file; + curr_line->li_addr_line.li_l_data.li_line = + (Dwarf_Sword) line; + curr_line->li_addr_line.li_l_data.li_column = + (Dwarf_Half) column; + curr_line->li_addr_line.li_l_data.li_is_stmt = + prefix.pf_default_is_stmt; + curr_line->li_addr_line.li_l_data. + li_basic_block = basic_block; + curr_line->li_addr_line.li_l_data. + li_end_sequence = end_sequence; + curr_line->li_context = line_context; + curr_line->li_addr_line.li_l_data. + li_epilogue_begin = epilogue_begin; + curr_line->li_addr_line.li_l_data. + li_prologue_end = prologue_end; + curr_line->li_addr_line.li_l_data.li_isa = isa; + line_count++; + + chain_line = (Dwarf_Chain) + _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (chain_line == NULL) { + dwarf_free_line_table_prefix(&prefix); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + chain_line->ch_item = curr_line; + + if (head_chain == NULL) + head_chain = curr_chain = chain_line; + else { + curr_chain->ch_next = chain_line; + curr_chain = chain_line; + } + } + + address = 0; + file = 1; + line = 1; + column = 0; + is_stmt = prefix.pf_default_is_stmt; + basic_block = false; + end_sequence = false; + prologue_end = false; + epilogue_begin = false; + + + break; + } + + case DW_LNE_set_address:{ + if (instr_length - 1 == dbg->de_pointer_size) { + READ_UNALIGNED(dbg, address, Dwarf_Addr, + line_ptr, dbg->de_pointer_size); + if (doaddrs) { + curr_line = + (Dwarf_Line) _dwarf_get_alloc(dbg, + DW_DLA_LINE, + 1); + if (curr_line == NULL) { + dwarf_free_line_table_prefix(&prefix); + _dwarf_error(dbg, error, + DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + curr_line->li_address = address; + curr_line->li_addr_line.li_offset = + line_ptr - dbg->de_debug_line; + + line_count++; + + chain_line = (Dwarf_Chain) + _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (chain_line == NULL) { + dwarf_free_line_table_prefix(&prefix); + _dwarf_error(dbg, error, + DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + chain_line->ch_item = curr_line; + + if (head_chain == NULL) + head_chain = curr_chain = chain_line; + else { + curr_chain->ch_next = chain_line; + curr_chain = chain_line; + } + } + + line_ptr += dbg->de_pointer_size; + } else { + dwarf_free_line_table_prefix(&prefix); + _dwarf_error(dbg, error, + DW_DLE_LINE_SET_ADDR_ERROR); + return (DW_DLV_ERROR); + } + + break; + } + + case DW_LNE_define_file:{ + + if (dolines) { + cur_file_entry = (Dwarf_File_Entry) + _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1); + if (cur_file_entry == NULL) { + dwarf_free_line_table_prefix(&prefix); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + cur_file_entry->fi_file_name = + (Dwarf_Small *) line_ptr; + line_ptr = + line_ptr + strlen((char *) line_ptr) + 1; + + cur_file_entry->fi_dir_index = (Dwarf_Sword) + _dwarf_decode_u_leb128(line_ptr, + &leb128_length); + line_ptr = line_ptr + leb128_length; + + cur_file_entry->fi_time_last_mod = + _dwarf_decode_u_leb128(line_ptr, + &leb128_length); + line_ptr = line_ptr + leb128_length; + + cur_file_entry->fi_file_length = + _dwarf_decode_u_leb128(line_ptr, + &leb128_length); + line_ptr = line_ptr + leb128_length; + + if (file_entries == NULL) + file_entries = cur_file_entry; + else + prev_file_entry->fi_next = cur_file_entry; + prev_file_entry = cur_file_entry; + + file_entry_count++; + } + break; + } + + default:{ + dwarf_free_line_table_prefix(&prefix); + _dwarf_error(dbg, error, + DW_DLE_LINE_EXT_OPCODE_BAD); + return (DW_DLV_ERROR); + } + } + + } + } + + block_line = (Dwarf_Line *) + _dwarf_get_alloc(dbg, DW_DLA_LIST, line_count); + if (block_line == NULL) { + dwarf_free_line_table_prefix(&prefix); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + curr_chain = head_chain; + for (i = 0; i < line_count; i++) { + *(block_line + i) = curr_chain->ch_item; + head_chain = curr_chain; + curr_chain = curr_chain->ch_next; + dwarf_dealloc(dbg, head_chain, DW_DLA_CHAIN); + } + + line_context->lc_file_entries = file_entries; + line_context->lc_file_entry_count = file_entry_count; + line_context->lc_include_directories_count = + prefix.pf_include_directories_count; + if (prefix.pf_include_directories_count > 0) { + /* This gets a pointer to the *first* include dir. The others + follow directly with the standard DWARF2/3 NUL byte + following the last. */ + line_context->lc_include_directories = + prefix.pf_include_directories[0]; + } + + line_context->lc_line_count = line_count; + line_context->lc_compilation_directory = comp_dir; + line_context->lc_version_number = prefix.pf_version; + line_context->lc_dbg = dbg; + *count = line_count; + + *linebuf = block_line; + dwarf_free_line_table_prefix(&prefix); + return (DW_DLV_OK); +} + +int +dwarf_srclines(Dwarf_Die die, + Dwarf_Line ** linebuf, + Dwarf_Signed * linecount, Dwarf_Error * error) +{ + Dwarf_Signed count; + int res; + + res = _dwarf_internal_srclines(die, linebuf, &count, /* addrlist= + */ false, + /* linelist= */ true, error); + if (res != DW_DLV_OK) { + return res; + } + *linecount = count; + return res; +} + + + +/* Every line table entry (except DW_DLE_end_sequence, + which is returned using dwarf_lineendsequence()) + potentially has the begin-statement + flag marked 'on'. This returns thru *return_bool, + the begin-statement flag. +*/ + +int +dwarf_linebeginstatement(Dwarf_Line line, + Dwarf_Bool * return_bool, Dwarf_Error * error) +{ + if (line == NULL || return_bool == 0) { + _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); + return (DW_DLV_ERROR); + } + + *return_bool = (line->li_addr_line.li_l_data.li_is_stmt); + return DW_DLV_OK; +} + +/* At the end of any contiguous line-table there may be + a DW_LNE_end_sequence operator. + This returns non-zero thru *return_bool + if and only if this 'line' entry was a DW_LNE_end_sequence. + + Within a compilation unit or function there may be multiple + line tables, each ending with a DW_LNE_end_sequence. + Each table describes a contiguous region. + Because compilers may split function code up in arbitrary ways + compilers may need to emit multiple contigous regions (ie + line tables) for a single function. + See the DWARF3 spec section 6.2. +*/ +int +dwarf_lineendsequence(Dwarf_Line line, + Dwarf_Bool * return_bool, Dwarf_Error * error) +{ + if (line == NULL) { + _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); + return (DW_DLV_ERROR); + } + + *return_bool = (line->li_addr_line.li_l_data.li_end_sequence); + return DW_DLV_OK; +} + + +/* Each 'line' entry has a line-number. + If the entry is a DW_LNE_end_sequence the line-number is + meaningless (see dwarf_lineendsequence(), just above). +*/ +int +dwarf_lineno(Dwarf_Line line, + Dwarf_Unsigned * ret_lineno, Dwarf_Error * error) +{ + if (line == NULL || ret_lineno == 0) { + _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); + return (DW_DLV_ERROR); + } + + *ret_lineno = (line->li_addr_line.li_l_data.li_line); + return DW_DLV_OK; +} + +/* Each 'line' entry has a file-number, and index into the file table. + If the entry is a DW_LNE_end_sequence the index is + meaningless (see dwarf_lineendsequence(), just above). + The file number returned is an index into the file table + produced by dwarf_srcfiles(), but care is required: the + li_file begins with 1 for real files, so that the li_file returned here + is 1 greater than its index into the dwarf_srcfiles() output array. + And entries from DW_LNE_define_file don't appear in + the dwarf_srcfiles() output so file indexes from here may exceed + the size of the dwarf_srcfiles() output array size. +*/ +int +dwarf_line_srcfileno(Dwarf_Line line, + Dwarf_Unsigned * ret_fileno, Dwarf_Error * error) +{ + if (line == NULL || ret_fileno == 0) { + _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); + return (DW_DLV_ERROR); + } + /* li_file must be <= line->li_context->lc_file_entry_count else it + is trash. li_file 0 means not attributable to any source file + per dwarf2/3 spec. */ + + *ret_fileno = (line->li_addr_line.li_l_data.li_file); + return DW_DLV_OK; +} + + +/* Each 'line' entry has a line-address. + If the entry is a DW_LNE_end_sequence the adddress + is one-beyond the last address this contigous region + covers, so the address is not inside the region, + but is just outside it. +*/ +int +dwarf_lineaddr(Dwarf_Line line, + Dwarf_Addr * ret_lineaddr, Dwarf_Error * error) +{ + if (line == NULL || ret_lineaddr == 0) { + _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); + return (DW_DLV_ERROR); + } + + *ret_lineaddr = (line->li_address); + return DW_DLV_OK; +} + + +/* Each 'line' entry has a column-within-line (offset + within the line) where the + source text begins. + If the entry is a DW_LNE_end_sequence the line-number is + meaningless (see dwarf_lineendsequence(), just above). + Lines of text begin at column 1. The value 0 + means the line begins at the left edge of the line. + (See the DWARF3 spec, section 6.2.2). +*/ +int +dwarf_lineoff(Dwarf_Line line, + Dwarf_Signed * ret_lineoff, Dwarf_Error * error) +{ + if (line == NULL || ret_lineoff == 0) { + _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); + return (DW_DLV_ERROR); + } + + *ret_lineoff = + (line->li_addr_line.li_l_data.li_column == + 0 ? -1 : line->li_addr_line.li_l_data.li_column); + return DW_DLV_OK; +} + + +int +dwarf_linesrc(Dwarf_Line line, char **ret_linesrc, Dwarf_Error * error) +{ + Dwarf_Signed i; + Dwarf_File_Entry file_entry; + Dwarf_Small *name_buffer; + Dwarf_Small *include_directories; + Dwarf_Debug dbg; + unsigned int comp_dir_len; + + if (line == NULL) { + _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); + return (DW_DLV_ERROR); + } + + if (line->li_context == NULL) { + _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL); + return (DW_DLV_ERROR); + } + dbg = line->li_context->lc_dbg; + + if (line->li_addr_line.li_l_data.li_file > + line->li_context->lc_file_entry_count) { + _dwarf_error(dbg, error, DW_DLE_LINE_FILE_NUM_BAD); + return (DW_DLV_ERROR); + } + + if (line->li_addr_line.li_l_data.li_file == 0) { + /* No file name known: see dwarf2/3 spec. */ + _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME); + return (DW_DLV_ERROR); + } + file_entry = line->li_context->lc_file_entries; + /* ASSERT: li_file > 0, dwarf correctness issue, see line table + definition of dwarf2/3 spec. */ + /* Example: if li_file is 2 and lc_file_entry_count is 3, + file_entry is file 3 (1 based), aka 2( 0 based) file_entry->next + is file 2 (1 based), aka 1( 0 based) file_entry->next->next is + file 1 (1 based), aka 0( 0 based) file_entry->next->next->next + is NULL. + + and this loop finds the file_entry we need (2 (1 based) in this + case). Because lc_file_entries are in reverse order and + effectively zero based as a count whereas li_file is 1 based. */ + for (i = line->li_addr_line.li_l_data.li_file - 1; i > 0; i--) + file_entry = file_entry->fi_next; + + if (file_entry->fi_file_name == NULL) { + _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME); + return (DW_DLV_ERROR); + } + + if (*(char *) file_entry->fi_file_name == '/') { + *ret_linesrc = ((char *) file_entry->fi_file_name); + return DW_DLV_OK; + } + + if (file_entry->fi_dir_index == 0) { + + /* dir_index of 0 means that the compilation was in the + 'current directory of compilation' */ + if (line->li_context->lc_compilation_directory == NULL) { + /* we don't actually *have* a current directory of + compilation: DW_AT_comp_dir was not present Rather than + emitting DW_DLE_NO_COMP_DIR lets just make an empty name + here. In other words, do the best we can with what we do + have instead of reporting an error. _dwarf_error(dbg, + error, DW_DLE_NO_COMP_DIR); return(DW_DLV_ERROR); */ + comp_dir_len = 0; + } else { + comp_dir_len = strlen((char *) + (line->li_context-> + lc_compilation_directory)); + } + + name_buffer = + _dwarf_get_alloc(line->li_context->lc_dbg, DW_DLA_STRING, + comp_dir_len + 1 + + strlen((char *) file_entry->fi_file_name) + + 1); + if (name_buffer == NULL) { + _dwarf_error(line->li_context->lc_dbg, error, + DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + if (comp_dir_len > 0) { + /* if comp_dir_len is 0 we do not want to put a / in front + of the fi_file_name as we just don't know anything. */ + strcpy((char *) name_buffer, + (char *) (line->li_context-> + lc_compilation_directory)); + strcat((char *) name_buffer, "/"); + } + strcat((char *) name_buffer, (char *) file_entry->fi_file_name); + *ret_linesrc = ((char *) name_buffer); + return DW_DLV_OK; + } + + if (file_entry->fi_dir_index > + line->li_context->lc_include_directories_count) { + _dwarf_error(dbg, error, DW_DLE_INCL_DIR_NUM_BAD); + return (DW_DLV_ERROR); + } + + include_directories = line->li_context->lc_include_directories; + for (i = file_entry->fi_dir_index - 1; i > 0; i--) + include_directories += strlen((char *) include_directories) + 1; + + if (line->li_context->lc_compilation_directory) { + comp_dir_len = strlen((char *) + (line->li_context-> + lc_compilation_directory)); + } else { + /* No DW_AT_comp_dir present. Do the best we can without it. */ + comp_dir_len = 0; + } + + name_buffer = _dwarf_get_alloc(dbg, DW_DLA_STRING, + (*include_directories == '/' ? + 0 : comp_dir_len + 1) + + strlen((char *) include_directories) + + 1 + + strlen((char *) file_entry-> + fi_file_name) + 1); + if (name_buffer == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + if (*include_directories != '/') { + if (comp_dir_len > 0) { + strcpy((char *) name_buffer, + (char *) line->li_context->lc_compilation_directory); + /* Who provides the / needed after the compilation + directory? */ + if (name_buffer[comp_dir_len - 1] != '/') { + /* Here we provide the / separator */ + name_buffer[comp_dir_len] = '/'; /* overwrite + previous nul + terminator + with needed + / */ + name_buffer[comp_dir_len + 1] = 0; + } + } + } else { + strcpy((char *) name_buffer, ""); + } + strcat((char *) name_buffer, (char *) include_directories); + strcat((char *) name_buffer, "/"); + strcat((char *) name_buffer, (char *) file_entry->fi_file_name); + *ret_linesrc = ((char *) name_buffer); + return DW_DLV_OK; +} + +/* Every line table entry potentially has the basic-block-start + flag marked 'on'. This returns thru *return_bool, + the basic-block-start flag. +*/ +int +dwarf_lineblock(Dwarf_Line line, + Dwarf_Bool * return_bool, Dwarf_Error * error) +{ + if (line == NULL) { + _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); + return (DW_DLV_ERROR); + } + + *return_bool = (line->li_addr_line.li_l_data.li_basic_block); + return DW_DLV_OK; +} + + +#if 0 /* Ignore this. This needs major + re-work. */ +/* + This routine works by looking for exact matches between + the current line address and pc, and crossovers from + from less than pc value to greater than. At each line + that satisfies the above, it records a pointer to the + line, and the difference between the address and pc. + It then scans these pointers and picks out those with + the smallest difference between pc and address. +*/ +int +dwarf_pclines(Dwarf_Debug dbg, + Dwarf_Addr pc, + Dwarf_Line ** linebuf, + Dwarf_Signed slide, + Dwarf_Signed * linecount, Dwarf_Error * error) +{ + /* + Scans the line matrix for the current cu to which a pointer + exists in dbg. */ + Dwarf_Line line; + Dwarf_Line prev_line; + + /* + These flags are for efficiency reasons. Check_line is true + initially, but set false when the address of the current line is + greater than pc. It is set true only when the address of the + current line falls below pc. This assumes that addresses within + the same segment increase, and we are only interested in the + switch from a less than pc address to a greater than. First_line + is set true initially, but set false after the first line is + scanned. This is to prevent looking at the address of previous + line when slide is DW_DLS_BACKWARD, and the first line is being + scanned. */ + Dwarf_Bool check_line, first_line; + + /* + Diff tracks the smallest difference a line address and the input + pc value. */ + Dwarf_Signed diff, i; + + /* + For the slide = DW_DLS_BACKWARD case, pc_less is the value of + the address of the line immediately preceding the first line + that has value greater than pc. For the slide = DW_DLS_FORWARD + case, pc_more is the values of address for the first line that + is greater than pc. Diff is the difference between either of the + these values and pc. */ + Dwarf_Addr pc_less, pc_more; + + /* + Pc_line_buf points to a chain of pointers to lines of which + those with a diff equal to the smallest difference will be + returned. */ + Dwarf_Line *pc_line_buf, *pc_line; + + /* + Chain_count counts the number of lines in the above chain for + which the diff is equal to the smallest difference This is the + number returned by this routine. */ + Dwarf_Signed chain_count; + + chain_head = NULL; + + check_line = true; + first_line = true; + diff = MAX_LINE_DIFF; + + for (i = 0; i < dbg->de_cu_line_count; i++) { + + line = *(dbg->de_cu_line_ptr + i); + prev_line = first_line ? NULL : *(dbg->de_cu_line_ptr + i - 1); + + if (line->li_address == pc) { + chain_ptr = (struct chain *) + _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (chain_ptr == NULL) { + _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + chain_ptr->line = line; + chain_ptr->diff = diff = 0; + chain_ptr->next = chain_head; + chain_head = chain_ptr; + } else + /* + Look for crossover from less than pc address to greater + than. */ + if (check_line && line->li_address > pc && + (first_line ? 0 : prev_line->li_address) < pc) + + if (slide == DW_DLS_BACKWARD && !first_line) { + pc_less = prev_line->li_address; + if (pc - pc_less <= diff) { + chain_ptr = (struct chain *) + _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (chain_ptr == NULL) { + _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + chain_ptr->line = prev_line; + chain_ptr->diff = diff = pc - pc_less; + chain_ptr->next = chain_head; + chain_head = chain_ptr; + } + check_line = false; + } else if (slide == DW_DLS_FORWARD) { + pc_more = line->li_address; + if (pc_more - pc <= diff) { + chain_ptr = (struct chain *) + _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (chain_ptr == NULL) { + _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + chain_ptr->line = line; + chain_ptr->diff = diff = pc_more - pc; + chain_ptr->next = chain_head; + chain_head = chain_ptr; + } + check_line = false; + } else + /* Check addresses only when they go */ + /* below pc. */ + if (line->li_address < pc) + check_line = true; + + first_line = false; + } + + chain_count = 0; + for (chain_ptr = chain_head; chain_ptr != NULL; + chain_ptr = chain_ptr->next) + if (chain_ptr->diff == diff) + chain_count++; + + pc_line_buf = pc_line = (Dwarf_Line) + _dwarf_get_alloc(dbg, DW_DLA_LIST, chain_count); + for (chain_ptr = chain_head; chain_ptr != NULL; + chain_ptr = chain_ptr->next) + if (chain_ptr->diff == diff) { + *pc_line = chain_ptr->line; + pc_line++; + } + + for (chain_ptr = chain_head; chain_ptr != NULL;) { + chain_head = chain_ptr; + chain_ptr = chain_ptr->next; + dwarf_dealloc(dbg, chain_head, DW_DLA_CHAIN); + } + + *linebuf = pc_line_buf; + return (chain_count); +} +#endif + + + +/* + It's impossible for callers of dwarf_srclines() to get to and + free all the resources (in particular, the li_context and its + lc_file_entries). + So this function, new July 2005, does it. +*/ + +void +dwarf_srclines_dealloc(Dwarf_Debug dbg, Dwarf_Line * linebuf, + Dwarf_Signed count) +{ + + Dwarf_Signed i = 0; + struct Dwarf_Line_Context_s *context = 0; + + if (count > 0) { + /* All these entries share a single context */ + context = linebuf[0]->li_context; + } + for (i = 0; i < count; ++i) { + dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE); + } + dwarf_dealloc(dbg, linebuf, DW_DLA_LIST); + + if (context) { + Dwarf_File_Entry fe = context->lc_file_entries; + + while (fe) { + Dwarf_File_Entry fenext = fe->fi_next; + + dwarf_dealloc(dbg, fe, DW_DLA_FILE_ENTRY); + fe = fenext; + } + dwarf_dealloc(dbg, context, DW_DLA_LINE_CONTEXT); + } + + return; +} + +/* Operand counts per standard operand. + The initial zero is for DW_LNS_copy. + This is an economical way to verify we understand the table + of standard-opcode-lengths in the line table prologue. */ +#define STANDARD_OPERAND_COUNT_DWARF2 9 +#define STANDARD_OPERAND_COUNT_DWARF3 12 +static unsigned char + dwarf_standard_opcode_operand_count[STANDARD_OPERAND_COUNT_DWARF3] = { + /* DWARF2 */ + 0, + 1, 1, 1, 1, + 0, 0, 0, + 1, + /* Following are new for DWARF3. */ + 0, 0, 1 +}; + +/* Common line table prefix reading code. + Returns DW_DLV_OK, DW_DLV_ERROR. + DW_DLV_NO_ENTRY cannot be returned, but callers should + assume it is possible. + + The prefix_out area must be initialized properly before calling this. + + Has the side effect of allocating arrays which + must be freed (see the Line_Table_Prefix_s struct which + holds the pointers to space we allocate here). +*/ +int +dwarf_read_line_table_prefix(Dwarf_Debug dbg, + Dwarf_Small * data_start, + Dwarf_Unsigned data_length, + Dwarf_Small ** updated_data_start_out, + struct Line_Table_Prefix_s *prefix_out, + Dwarf_Error * err) +{ + Dwarf_Small *line_ptr = data_start; + Dwarf_Unsigned total_length = 0; + int local_length_size = 0; + int local_extension_size = 0; + Dwarf_Unsigned prologue_length = 0; + Dwarf_Half version = 0; + Dwarf_Unsigned directories_count = 0; + Dwarf_Unsigned directories_malloc = 0; + Dwarf_Unsigned files_count = 0; + Dwarf_Unsigned files_malloc = 0; + Dwarf_Small *line_ptr_end = 0; + + prefix_out->pf_line_ptr_start = line_ptr; + /* READ_AREA_LENGTH updates line_ptr for consumed bytes */ + READ_AREA_LENGTH(dbg, total_length, Dwarf_Unsigned, + line_ptr, local_length_size, local_extension_size); + + + line_ptr_end = line_ptr + total_length; + prefix_out->pf_line_ptr_end = line_ptr_end; + prefix_out->pf_length_field_length = local_length_size + + local_extension_size; + /* ASSERT: prefix_out->pf_length_field_length == line_ptr + -prefix_out->pf_line_ptr_start; */ + if (line_ptr_end > dbg->de_debug_line + dbg->de_debug_line_size) { + _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); + return (DW_DLV_ERROR); + } + if (line_ptr_end > data_start + data_length) { + _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); + return (DW_DLV_ERROR); + } + prefix_out->pf_total_length = total_length; + + READ_UNALIGNED(dbg, version, Dwarf_Half, + line_ptr, sizeof(Dwarf_Half)); + prefix_out->pf_version = version; + line_ptr += sizeof(Dwarf_Half); + if (version != CURRENT_VERSION_STAMP && + version != CURRENT_VERSION_STAMP3) { + _dwarf_error(dbg, err, DW_DLE_VERSION_STAMP_ERROR); + return (DW_DLV_ERROR); + } + + READ_UNALIGNED(dbg, prologue_length, Dwarf_Unsigned, + line_ptr, local_length_size); + prefix_out->pf_prologue_length = prologue_length; + line_ptr += local_length_size; + prefix_out->pf_line_prologue_start = line_ptr; + + + prefix_out->pf_minimum_instruction_length = + *(unsigned char *) line_ptr; + line_ptr = line_ptr + sizeof(Dwarf_Small); + + prefix_out->pf_default_is_stmt = *(unsigned char *) line_ptr; + line_ptr = line_ptr + sizeof(Dwarf_Small); + + prefix_out->pf_line_base = *(signed char *) line_ptr; + line_ptr = line_ptr + sizeof(Dwarf_Sbyte); + + prefix_out->pf_line_range = *(unsigned char *) line_ptr; + line_ptr = line_ptr + sizeof(Dwarf_Small); + + prefix_out->pf_opcode_base = *(unsigned char *) line_ptr; + line_ptr = line_ptr + sizeof(Dwarf_Small); + + /* Set up the array of standard opcode lengths. */ + /* We think this works ok even for cross-endian processing of + objects. It might be wrong, we might need to specially process + the array of ubyte into host order. */ + prefix_out->pf_opcode_length_table = line_ptr; + + /* pf_opcode_base is one greater than the size of the array. */ + line_ptr += prefix_out->pf_opcode_base - 1; + + { + /* Determine (as best we can) whether the + pf_opcode_length_table holds 9 or 12 standard-conforming + entries. gcc4 upped to DWARF3's 12 without updating the + version number. */ + int operand_ck_fail = true; + + if (prefix_out->pf_opcode_base >= STANDARD_OPERAND_COUNT_DWARF3) { + int mismatch = memcmp(dwarf_standard_opcode_operand_count, + prefix_out->pf_opcode_length_table, + STANDARD_OPERAND_COUNT_DWARF3); + + if (!mismatch) { + operand_ck_fail = false; + prefix_out->pf_std_op_count = + STANDARD_OPERAND_COUNT_DWARF3; + } + + } + if (operand_ck_fail) { + if (prefix_out->pf_opcode_base >= + STANDARD_OPERAND_COUNT_DWARF2) { + + int mismatch = + memcmp(dwarf_standard_opcode_operand_count, + prefix_out->pf_opcode_length_table, + STANDARD_OPERAND_COUNT_DWARF2); + + if (!mismatch) { + operand_ck_fail = false; + prefix_out->pf_std_op_count = + STANDARD_OPERAND_COUNT_DWARF2; + } + } + } + if (operand_ck_fail) { + _dwarf_error(dbg, err, DW_DLE_LINE_NUM_OPERANDS_BAD); + return (DW_DLV_ERROR); + } + } + /* At this point we no longer need to check operand counts. */ + + + directories_count = 0; + directories_malloc = 5; + prefix_out->pf_include_directories = malloc(sizeof(Dwarf_Small *) * + directories_malloc); + if (prefix_out->pf_include_directories == NULL) { + _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + memset(prefix_out->pf_include_directories, 0, + sizeof(Dwarf_Small *) * directories_malloc); + + while ((*(char *) line_ptr) != '\0') { + if (directories_count >= directories_malloc) { + Dwarf_Unsigned expand = 2 * directories_malloc; + Dwarf_Unsigned bytesalloc = sizeof(Dwarf_Small *) * expand; + Dwarf_Small **newdirs = + realloc(prefix_out->pf_include_directories, + bytesalloc); + + if (!newdirs) { + _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + /* Doubled size, zero out second half. */ + memset(newdirs + directories_malloc, 0, + sizeof(Dwarf_Small *) * directories_malloc); + directories_malloc = expand; + prefix_out->pf_include_directories = newdirs; + } + prefix_out->pf_include_directories[directories_count] = + line_ptr; + line_ptr = line_ptr + strlen((char *) line_ptr) + 1; + directories_count++; + } + prefix_out->pf_include_directories_count = directories_count; + line_ptr++; + + files_count = 0; + files_malloc = 5; + prefix_out->pf_line_table_file_entries = + malloc(sizeof(struct Line_Table_File_Entry_s) * files_malloc); + if (prefix_out->pf_line_table_file_entries == NULL) { + _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + memset(prefix_out->pf_line_table_file_entries, 0, + sizeof(struct Line_Table_File_Entry_s) * files_malloc); + + while (*(char *) line_ptr != '\0') { + Dwarf_Unsigned utmp; + Dwarf_Unsigned dir_index = 0; + Dwarf_Unsigned lastmod = 0; + Dwarf_Unsigned file_length = 0; + struct Line_Table_File_Entry_s *curline; + Dwarf_Word leb128_length = 0; + + + if (files_count >= files_malloc) { + Dwarf_Unsigned expand = 2 * files_malloc; + struct Line_Table_File_Entry_s *newfiles = + realloc(prefix_out->pf_line_table_file_entries, + sizeof(struct Line_Table_File_Entry_s) * + expand); + if (!newfiles) { + _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + memset(newfiles + files_malloc, 0, + sizeof(struct Line_Table_File_Entry_s) * + files_malloc); + files_malloc = expand; + prefix_out->pf_line_table_file_entries = newfiles; + } + curline = prefix_out->pf_line_table_file_entries + files_count; + + curline->lte_filename = line_ptr; + line_ptr = line_ptr + strlen((char *) line_ptr) + 1; + + DECODE_LEB128_UWORD(line_ptr, utmp); + dir_index = (Dwarf_Sword) utmp; + if (dir_index > directories_count) { + _dwarf_error(dbg, err, DW_DLE_DIR_INDEX_BAD); + return (DW_DLV_ERROR); + } + curline->lte_directory_index = dir_index; + + lastmod = _dwarf_decode_u_leb128(line_ptr, &leb128_length); + line_ptr = line_ptr + leb128_length; + curline->lte_last_modification_time = lastmod; + + /* Skip over file length. */ + file_length = _dwarf_decode_u_leb128(line_ptr, &leb128_length); + line_ptr = line_ptr + leb128_length; + curline->lte_length_of_file = file_length; + + ++files_count; + + } + prefix_out->pf_files_count = files_count; + /* Skip trailing nul byte */ + ++line_ptr; + + + if (line_ptr != (prefix_out->pf_line_prologue_start + + prefix_out->pf_prologue_length)) { + _dwarf_error(dbg, err, DW_DLE_LINE_PROLOG_LENGTH_BAD); + return (DW_DLV_ERROR); + } + + + *updated_data_start_out = line_ptr; + return DW_DLV_OK; +} + + +/* Initialize the Line_Table_Prefix_s struct. + memset is not guaranteed a portable initializer, but works + fine for current architectures. AFAIK. +*/ +void +dwarf_init_line_table_prefix(struct Line_Table_Prefix_s *pf) +{ + memset(pf, 0, sizeof(*pf)); +} + +/* Free any malloc'd area. of the Line_Table_Prefix_s struct. */ +void +dwarf_free_line_table_prefix(struct Line_Table_Prefix_s *pf) +{ + if (pf->pf_include_directories) { + free(pf->pf_include_directories); + pf->pf_include_directories = 0; + } + if (pf->pf_line_table_file_entries) { + free(pf->pf_line_table_file_entries); + pf->pf_line_table_file_entries = 0; + } + return; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_line.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_line.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,320 @@ +/* + + Copyright (C) 2000, 2004, 2006 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#define DW_EXTENDED_OPCODE 0 + +/* + This is used as the starting value for an algorithm + to get the minimum difference between 2 values. + UINT_MAX is used as our approximation to infinity. +*/ +#define MAX_LINE_DIFF UINT_MAX + + +/* + This structure is used to build a list of all the + files that are used in the current compilation unit. + All of the fields execpt fi_next have meanings that + are obvious from section 6.2.4 of the Libdwarf Doc. +*/ +struct Dwarf_File_Entry_s { + /* Points to string naming the file. */ + Dwarf_Small *fi_file_name; + + /* + Index into the list of directories of the directory in which + this file exits. */ + Dwarf_Sword fi_dir_index; + + /* Time of last modification of the file. */ + Dwarf_Unsigned fi_time_last_mod; + + /* Length in bytes of the file. */ + Dwarf_Unsigned fi_file_length; + + /* Pointer for chaining file entries. */ + Dwarf_File_Entry fi_next; +}; + + +typedef struct Dwarf_Line_Context_s *Dwarf_Line_Context; + +/* + This structure provides the context in which the fields of + a Dwarf_Line structure are interpreted. They come from the + statement program prologue. **Updated by dwarf_srclines in + dwarf_line.c. +*/ +struct Dwarf_Line_Context_s { + /* + Points to a chain of entries providing info about source files + for the current set of Dwarf_Line structures. File number + 'li_file 1' is last on the list, the first list entry is the + file numbered lc_file_entry_count. The numbering of the file + names matches the dwarf2/3 line table specification file table + and DW_LNE_define_file numbering rules. */ + Dwarf_File_Entry lc_file_entries; + /* + Count of number of source files for this set of Dwarf_Line + structures. */ + Dwarf_Sword lc_file_entry_count; + /* + Points to the portion of .debug_line section that contains a + list of strings naming the included directories. */ + Dwarf_Small *lc_include_directories; + + /* Count of the number of included directories. */ + Dwarf_Sword lc_include_directories_count; + + /* Count of the number of lines for this cu. */ + Dwarf_Sword lc_line_count; + + /* Points to name of compilation directory. */ + Dwarf_Small *lc_compilation_directory; + + Dwarf_Debug lc_dbg; + + Dwarf_Half lc_version_number; /* DWARF2/3 version number, 2 + for DWARF2, 3 for DWARF3. */ +}; + + +/* + This structure defines a row of the line table. + All of the fields except li_offset have the exact + same meaning that is defined in Section 6.2.2 + of the Libdwarf Document. + + li_offset is used by _dwarf_addr_finder() which is called + by rqs(1), an sgi utility for 'moving' shared libraries + as if the static linker (ld) had linked the shared library + at the newly-specified address. Most libdwarf-using + apps will ignore li_offset and _dwarf_addr_finder(). + +*/ +struct Dwarf_Line_s { + Dwarf_Addr li_address; /* pc value of machine instr */ + union addr_or_line_s { + struct li_inner_s { + Dwarf_Sword li_file; /* int identifying src file */ + /* li_file is a number 1-N, indexing into a conceptual + source file table as described in dwarf2/3 spec line + table doc. (see Dwarf_File_Entry lc_file_entries; and + Dwarf_Sword lc_file_entry_count;) */ + + Dwarf_Sword li_line; /* source file line number. */ + Dwarf_Half li_column; /* source file column number */ + Dwarf_Small li_isa; + + /* To save space, use bit flags. */ + /* indicate start of stmt */ + unsigned char li_is_stmt:1; + + /* indicate start basic block */ + unsigned char li_basic_block:1; + + /* first post sequence instr */ + unsigned char li_end_sequence:1; + + unsigned char li_prologue_end:1; + unsigned char li_epilogue_begin:1; + } li_l_data; + Dwarf_Off li_offset; /* for rqs */ + } li_addr_line; + Dwarf_Line_Context li_context; /* assoc Dwarf_Line_Context_s */ +}; + + +int _dwarf_line_address_offsets(Dwarf_Debug dbg, + Dwarf_Die die, + Dwarf_Addr ** addrs, + Dwarf_Off ** offs, + Dwarf_Unsigned * returncount, + Dwarf_Error * err); +int _dwarf_internal_srclines(Dwarf_Die die, + Dwarf_Line ** linebuf, + Dwarf_Signed * count, + Dwarf_Bool doaddrs, + Dwarf_Bool dolines, Dwarf_Error * error); + + + +/* The LOP, WHAT_IS_OPCODE stuff is here so it can + be reused in 3 places. Seemed hard to keep + the 3 places the same without an inline func or + a macro. + + Handling the line section where the header and the + file being processed do not match (unusual, but + planned for in the design of .debug_line) + is too tricky to recode this several times and keep + it right. + + As it is the code starting up line-reading is duplicated + and that is just wrong to do. FIXME! +*/ +#define LOP_EXTENDED 1 +#define LOP_DISCARD 2 +#define LOP_STANDARD 3 +#define LOP_SPECIAL 4 + +#define WHAT_IS_OPCODE(type,opcode,base,opcode_length,line_ptr,highest_std) \ + if( (opcode) < (base) ) { \ + /* we know we must treat as a standard op \ + or a special case. \ + */ \ + if((opcode) == DW_EXTENDED_OPCODE) { \ + type = LOP_EXTENDED; \ + } else if( ((highest_std)+1) >= (base)) { \ + /* == Standard case: compile of \ + dwarf_line.c and object \ + have same standard op codes set. \ + \ + > Special case: compile of dwarf_line.c\ + has things in standard op codes list \ + in dwarf.h header not \ + in the object: handle this as a standard\ + op code in switch below. \ + The header special ops overlap the \ + object standard ops. \ + The new standard op codes will not \ + appear in the object. \ + */ \ + type = LOP_STANDARD; \ + } else { \ + /* These are standard opcodes in the object\ + ** that were not defined in the header \ + ** at the time dwarf_line.c \ + ** was compiled. Provides the ability of \ + ** out-of-date dwarf reader to read newer \ + ** line table data transparently. \ + */ \ + type = LOP_DISCARD; \ + } \ + \ + } else { \ + /* Is a special op code. \ + */ \ + type = LOP_SPECIAL; \ + } + +/* The following is from the dwarf definition of 'ubyte' + and is specifically mentioned in section 6.2.5.1, page 54 + of the Rev 2.0.0 dwarf specification. +*/ + +#define MAX_LINE_OP_CODE 255 + + +/* The following structs (Line_Table_File_Entry_s,Line_Table_Prefix_s) + and functions allow refactoring common code into a single + reader routine. +*/ +/* There can be zero of more of these needed for 1 line prologue. */ +struct Line_Table_File_Entry_s { + Dwarf_Small *lte_filename; + Dwarf_Unsigned lte_directory_index; + Dwarf_Unsigned lte_last_modification_time; + Dwarf_Unsigned lte_length_of_file; +}; + +/* Data picked up from the line table prologue for a single +CU. */ +struct Line_Table_Prefix_s { + + /* pf_total_length is the value of the length field for the line + table of this CU. So it does not count the length of itself (the + length value) for consistency with the say lenghts recorded in + DWARF2/3. */ + Dwarf_Unsigned pf_total_length; + + /* Length of the initial length field itself. */ + Dwarf_Half pf_length_field_length; + + /* The version is 2 for DWARF2, 3 for DWARF3 */ + Dwarf_Half pf_version; + + Dwarf_Unsigned pf_prologue_length; + Dwarf_Small pf_minimum_instruction_length; + + /* Start and end of this CU line area. pf_line_ptr_start + + pf_total_length + pf_length_field_length == pf_line_ptr_end. + Meaning pf_line_ptr_start is before the length info. */ + Dwarf_Small *pf_line_ptr_start; + Dwarf_Small *pf_line_ptr_end; + + /* Used to check that decoding of the line prologue is done right. */ + Dwarf_Small *pf_line_prologue_start; + + Dwarf_Small pf_default_is_stmt; + Dwarf_Sbyte pf_line_base; + Dwarf_Small pf_line_range; + + /* Highest std opcode (+1). */ + Dwarf_Small pf_opcode_base; + + /* pf_opcode_base -1 entries (each a count, normally the value of + each entry is 0 or 1). */ + Dwarf_Small *pf_opcode_length_table; + + Dwarf_Unsigned pf_include_directories_count; + /* Array of pointers to dir strings. pf_include_directories_count + entriesin the array. */ + Dwarf_Small **pf_include_directories; + + /* Count of entries in line_table_file_entries array. */ + Dwarf_Unsigned pf_files_count; + struct Line_Table_File_Entry_s *pf_line_table_file_entries; + + /* The number to treat as standard ops. This is a special + accomodation of gcc using the new standard opcodes but not + updating the version number. It's legal dwarf2, but much better + for the user to understand as dwarf3 when 'it looks ok'. */ + Dwarf_Bool pf_std_op_count; + +}; + +void dwarf_init_line_table_prefix(struct Line_Table_Prefix_s *pf); +void dwarf_free_line_table_prefix(struct Line_Table_Prefix_s *pf); + +int + dwarf_read_line_table_prefix(Dwarf_Debug dbg, + Dwarf_Small * data_start, + Dwarf_Unsigned data_length, + Dwarf_Small ** updated_data_start_out, + struct Line_Table_Prefix_s *prefix_out, + Dwarf_Error * err); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_line2.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_line2.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,114 @@ +/* + + Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + +/* This source file used for SGI-IRIX rqs processing. + Unused otherwise. +*/ + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_line.h" +#ifdef HAVE_ALLOCA_H +#include +#endif + + + +/* + Return DW_DLV_OK or, if error, + DW_DLV_ERROR. + + Thru pointers, return 2 arrays and a count + for rqs. +*/ +int +_dwarf_line_address_offsets(Dwarf_Debug dbg, + Dwarf_Die die, + Dwarf_Addr ** addrs, + Dwarf_Off ** offs, + Dwarf_Unsigned * returncount, + Dwarf_Error * err) +{ + Dwarf_Addr *laddrs; + Dwarf_Off *loffsets; + Dwarf_Signed lcount; + Dwarf_Signed i; + int res; + Dwarf_Line *linebuf; + + res = _dwarf_internal_srclines(die, &linebuf, &lcount, /* addrlist= + */ true, + /* linelist= */ false, err); + if (res != DW_DLV_OK) { + return res; + } + laddrs = (Dwarf_Addr *) + _dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount); + if (laddrs == NULL) { + dwarf_srclines_dealloc(dbg, linebuf, lcount); + _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + loffsets = (Dwarf_Off *) + _dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount); + if (loffsets == NULL) { + dwarf_srclines_dealloc(dbg, linebuf, lcount); + /* We already allocated what laddrs points at, so we'e better + deallocate that space since we are not going to return the + pointer to the caller. */ + dwarf_dealloc(dbg, laddrs, DW_DLA_ADDR); + _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + for (i = 0; i < lcount; i++) { + laddrs[i] = linebuf[i]->li_address; + loffsets[i] = linebuf[i]->li_addr_line.li_offset; + } + dwarf_srclines_dealloc(dbg, linebuf, lcount); + *returncount = lcount; + *offs = loffsets; + *addrs = laddrs; + return DW_DLV_OK; +} + +/* + It's impossible for callers of dwarf_srclines() to get to and + free all the resources (in particular, the li_context and its + lc_file_entries). + So this function, new July 2005, does it. +*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_loc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_loc.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1018 @@ +/* + + Copyright (C) 2000,2003,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + + + +#include "config.h" +#include "dwarf_incl.h" +#include "dwarf_loc.h" + + +/* + Given a Dwarf_Block that represents a location expression, + this function returns a pointer to a Dwarf_Locdesc struct + that has its ld_cents field set to the number of location + operators in the block, and its ld_s field pointing to a + contiguous block of Dwarf_Loc structs. However, the + ld_lopc and ld_hipc values are uninitialized. Returns + NULL on error. This function assumes that the length of + the block is greater than 0. Zero length location expressions + to represent variables that have been optimized away are + handled in the calling function. +*/ +static Dwarf_Locdesc * +_dwarf_get_locdesc(Dwarf_Debug dbg, + Dwarf_Block * loc_block, + Dwarf_Addr lowpc, + Dwarf_Addr highpc, Dwarf_Error * error) +{ + /* Size of the block containing the location expression. */ + Dwarf_Unsigned loc_len = 0; + + /* Sweeps the block containing the location expression. */ + Dwarf_Small *loc_ptr = 0; + + /* Current location operator. */ + Dwarf_Small atom = 0; + + /* Offset of current operator from start of block. */ + Dwarf_Unsigned offset = 0; + + /* Operands of current location operator. */ + Dwarf_Unsigned operand1, operand2; + + /* Used to chain the Dwarf_Loc_Chain_s structs. */ + Dwarf_Loc_Chain curr_loc = NULL; + Dwarf_Loc_Chain prev_loc = NULL; + Dwarf_Loc_Chain head_loc = NULL; + + /* Count of the number of location operators. */ + Dwarf_Unsigned op_count = 0; + + /* Contiguous block of Dwarf_Loc's for Dwarf_Locdesc. */ + Dwarf_Loc *block_loc = 0; + + /* Dwarf_Locdesc pointer to be returned. */ + Dwarf_Locdesc *locdesc = 0; + + Dwarf_Word leb128_length = 0; + Dwarf_Unsigned i = 0; + + /* ***** BEGIN CODE ***** */ + + loc_len = loc_block->bl_len; + loc_ptr = loc_block->bl_data; + + offset = 0; + op_count = 0; + while (offset < loc_len) { + + operand1 = 0; + operand2 = 0; + op_count++; + + atom = *(Dwarf_Small *) loc_ptr; + loc_ptr++; + offset++; + + curr_loc = + (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN, + 1); + if (curr_loc == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (NULL); + } + curr_loc->lc_offset = offset; + curr_loc->lc_atom = atom; + switch (atom) { + + case DW_OP_reg0: + case DW_OP_reg1: + case DW_OP_reg2: + case DW_OP_reg3: + case DW_OP_reg4: + case DW_OP_reg5: + case DW_OP_reg6: + case DW_OP_reg7: + case DW_OP_reg8: + case DW_OP_reg9: + case DW_OP_reg10: + case DW_OP_reg11: + case DW_OP_reg12: + case DW_OP_reg13: + case DW_OP_reg14: + case DW_OP_reg15: + case DW_OP_reg16: + case DW_OP_reg17: + case DW_OP_reg18: + case DW_OP_reg19: + case DW_OP_reg20: + case DW_OP_reg21: + case DW_OP_reg22: + case DW_OP_reg23: + case DW_OP_reg24: + case DW_OP_reg25: + case DW_OP_reg26: + case DW_OP_reg27: + case DW_OP_reg28: + case DW_OP_reg29: + case DW_OP_reg30: + case DW_OP_reg31: + break; + + case DW_OP_regx: + operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length); + loc_ptr = loc_ptr + leb128_length; + offset = offset + leb128_length; + break; + + case DW_OP_lit0: + case DW_OP_lit1: + case DW_OP_lit2: + case DW_OP_lit3: + case DW_OP_lit4: + case DW_OP_lit5: + case DW_OP_lit6: + case DW_OP_lit7: + case DW_OP_lit8: + case DW_OP_lit9: + case DW_OP_lit10: + case DW_OP_lit11: + case DW_OP_lit12: + case DW_OP_lit13: + case DW_OP_lit14: + case DW_OP_lit15: + case DW_OP_lit16: + case DW_OP_lit17: + case DW_OP_lit18: + case DW_OP_lit19: + case DW_OP_lit20: + case DW_OP_lit21: + case DW_OP_lit22: + case DW_OP_lit23: + case DW_OP_lit24: + case DW_OP_lit25: + case DW_OP_lit26: + case DW_OP_lit27: + case DW_OP_lit28: + case DW_OP_lit29: + case DW_OP_lit30: + case DW_OP_lit31: + operand1 = atom - DW_OP_lit0; + break; + + case DW_OP_addr: + READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, + loc_ptr, dbg->de_pointer_size); + loc_ptr += dbg->de_pointer_size; + offset += dbg->de_pointer_size; + break; + + case DW_OP_const1u: + operand1 = *(Dwarf_Small *) loc_ptr; + loc_ptr = loc_ptr + 1; + offset = offset + 1; + break; + + case DW_OP_const1s: + operand1 = *(Dwarf_Sbyte *) loc_ptr; + SIGN_EXTEND(operand1,1); + loc_ptr = loc_ptr + 1; + offset = offset + 1; + break; + + case DW_OP_const2u: + READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2); + loc_ptr = loc_ptr + 2; + offset = offset + 2; + break; + + case DW_OP_const2s: + READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2); + SIGN_EXTEND(operand1,2); + loc_ptr = loc_ptr + 2; + offset = offset + 2; + break; + + case DW_OP_const4u: + READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4); + loc_ptr = loc_ptr + 4; + offset = offset + 4; + break; + + case DW_OP_const4s: + READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4); + SIGN_EXTEND(operand1,4); + loc_ptr = loc_ptr + 4; + offset = offset + 4; + break; + + case DW_OP_const8u: + READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8); + loc_ptr = loc_ptr + 8; + offset = offset + 8; + break; + + case DW_OP_const8s: + READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8); + loc_ptr = loc_ptr + 8; + offset = offset + 8; + break; + + case DW_OP_constu: + operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length); + loc_ptr = loc_ptr + leb128_length; + offset = offset + leb128_length; + break; + + case DW_OP_consts: + operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length); + loc_ptr = loc_ptr + leb128_length; + offset = offset + leb128_length; + break; + + case DW_OP_fbreg: + operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length); + loc_ptr = loc_ptr + leb128_length; + offset = offset + leb128_length; + break; + + case DW_OP_breg0: + case DW_OP_breg1: + case DW_OP_breg2: + case DW_OP_breg3: + case DW_OP_breg4: + case DW_OP_breg5: + case DW_OP_breg6: + case DW_OP_breg7: + case DW_OP_breg8: + case DW_OP_breg9: + case DW_OP_breg10: + case DW_OP_breg11: + case DW_OP_breg12: + case DW_OP_breg13: + case DW_OP_breg14: + case DW_OP_breg15: + case DW_OP_breg16: + case DW_OP_breg17: + case DW_OP_breg18: + case DW_OP_breg19: + case DW_OP_breg20: + case DW_OP_breg21: + case DW_OP_breg22: + case DW_OP_breg23: + case DW_OP_breg24: + case DW_OP_breg25: + case DW_OP_breg26: + case DW_OP_breg27: + case DW_OP_breg28: + case DW_OP_breg29: + case DW_OP_breg30: + case DW_OP_breg31: + operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length); + loc_ptr = loc_ptr + leb128_length; + offset = offset + leb128_length; + break; + + case DW_OP_bregx: + /* uleb reg num followed by sleb offset */ + operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length); + loc_ptr = loc_ptr + leb128_length; + offset = offset + leb128_length; + + operand2 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length); + loc_ptr = loc_ptr + leb128_length; + offset = offset + leb128_length; + break; + + case DW_OP_dup: + case DW_OP_drop: + break; + + case DW_OP_pick: + operand1 = *(Dwarf_Small *) loc_ptr; + loc_ptr = loc_ptr + 1; + offset = offset + 1; + break; + + case DW_OP_over: + case DW_OP_swap: + case DW_OP_rot: + case DW_OP_deref: + break; + + case DW_OP_deref_size: + operand1 = *(Dwarf_Small *) loc_ptr; + loc_ptr = loc_ptr + 1; + offset = offset + 1; + break; + + case DW_OP_xderef: + break; + + case DW_OP_xderef_size: + operand1 = *(Dwarf_Small *) loc_ptr; + loc_ptr = loc_ptr + 1; + offset = offset + 1; + break; + + case DW_OP_abs: + case DW_OP_and: + case DW_OP_div: + case DW_OP_minus: + case DW_OP_mod: + case DW_OP_mul: + case DW_OP_neg: + case DW_OP_not: + case DW_OP_or: + case DW_OP_plus: + break; + + case DW_OP_plus_uconst: + operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length); + loc_ptr = loc_ptr + leb128_length; + offset = offset + leb128_length; + break; + + case DW_OP_shl: + case DW_OP_shr: + case DW_OP_shra: + case DW_OP_xor: + break; + + case DW_OP_le: + case DW_OP_ge: + case DW_OP_eq: + case DW_OP_lt: + case DW_OP_gt: + case DW_OP_ne: + break; + + case DW_OP_skip: + case DW_OP_bra: + READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2); + loc_ptr = loc_ptr + 2; + offset = offset + 2; + break; + + case DW_OP_piece: + operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length); + loc_ptr = loc_ptr + leb128_length; + offset = offset + leb128_length; + break; + + case DW_OP_nop: + break; + case DW_OP_push_object_address: /* DWARF3 */ + break; + case DW_OP_call2: /* DWARF3 */ + READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2); + loc_ptr = loc_ptr + 2; + offset = offset + 2; + break; + + case DW_OP_call4: /* DWARF3 */ + READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4); + loc_ptr = loc_ptr + 4; + offset = offset + 4; + break; + case DW_OP_call_ref: /* DWARF3 */ + READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, + dbg->de_length_size); + loc_ptr = loc_ptr + dbg->de_length_size; + offset = offset + dbg->de_length_size; + break; + + case DW_OP_form_tls_address: /* DWARF3f */ + break; + case DW_OP_call_frame_cfa: /* DWARF3f */ + break; + case DW_OP_bit_piece: /* DWARF3f */ + /* uleb size in bits followed by uleb offset in bits */ + operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length); + loc_ptr = loc_ptr + leb128_length; + offset = offset + leb128_length; + + operand2 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length); + loc_ptr = loc_ptr + leb128_length; + offset = offset + leb128_length; + break; + + + default: + _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD); + return (NULL); + } + + + curr_loc->lc_number = operand1; + curr_loc->lc_number2 = operand2; + + if (head_loc == NULL) + head_loc = prev_loc = curr_loc; + else { + prev_loc->lc_next = curr_loc; + prev_loc = curr_loc; + } + } + + block_loc = + (Dwarf_Loc *) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK, op_count); + if (block_loc == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (NULL); + } + + curr_loc = head_loc; + for (i = 0; i < op_count; i++) { + (block_loc + i)->lr_atom = curr_loc->lc_atom; + (block_loc + i)->lr_number = curr_loc->lc_number; + (block_loc + i)->lr_number2 = curr_loc->lc_number2; + (block_loc + i)->lr_offset = curr_loc->lc_offset; + + prev_loc = curr_loc; + curr_loc = curr_loc->lc_next; + dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN); + } + + locdesc = + (Dwarf_Locdesc *) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC, 1); + if (locdesc == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (NULL); + } + + locdesc->ld_cents = op_count; + locdesc->ld_s = block_loc; + locdesc->ld_from_loclist = loc_block->bl_from_loclist; + locdesc->ld_section_offset = loc_block->bl_section_offset; + locdesc->ld_lopc = lowpc; + locdesc->ld_hipc = highpc; + + return (locdesc); +} + +/* Using a loclist offset to get the in-memory + address of .debug_loc data to read, returns the loclist + 'header' info in return_block. +*/ + +#define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff) + +static int +_dwarf_read_loc_section(Dwarf_Debug dbg, + Dwarf_Block * return_block, + Dwarf_Addr * lowpc, Dwarf_Addr * hipc, + Dwarf_Off sec_offset, Dwarf_Error * error) +{ + Dwarf_Small *beg = dbg->de_debug_loc + sec_offset; + int address_size = dbg->de_pointer_size; + + Dwarf_Addr start_addr = 0; + Dwarf_Addr end_addr = 0; + Dwarf_Half exprblock_size = 0; + Dwarf_Unsigned exprblock_off = + 2 * address_size + sizeof(Dwarf_Half); + + if (sec_offset >= dbg->de_debug_loc_size) { + /* We're at the end. No more present. */ + return DW_DLV_NO_ENTRY; + } + + /* If it goes past end, error */ + if (exprblock_off > dbg->de_debug_loc_size) { + _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT); + return DW_DLV_ERROR; + } + + READ_UNALIGNED(dbg, start_addr, Dwarf_Addr, beg, address_size); + READ_UNALIGNED(dbg, end_addr, Dwarf_Addr, + beg + address_size, address_size); + if (start_addr == 0 && end_addr == 0) { + /* If start_addr and end_addr are 0, it's the end and no + exprblock_size field follows. */ + exprblock_size = 0; + exprblock_off -= sizeof(Dwarf_Half); + } else if (start_addr == MAX_ADDR) { + /* end address is a base address, no exprblock_size field here + either */ + exprblock_size = 0; + exprblock_off -= sizeof(Dwarf_Half); + } else { + + READ_UNALIGNED(dbg, exprblock_size, Dwarf_Half, + beg + 2 * address_size, sizeof(Dwarf_Half)); + /* exprblock_size can be zero, means no expression */ + if ((exprblock_off + exprblock_size) > dbg->de_debug_loc_size) { + _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT); + return DW_DLV_ERROR; + } + } +#undef MAX_ADDR + *lowpc = start_addr; + *hipc = end_addr; + + return_block->bl_len = exprblock_size; + return_block->bl_from_loclist = 1; + return_block->bl_data = beg + exprblock_off; + return_block->bl_section_offset = + ((Dwarf_Small *) return_block->bl_data) - dbg->de_debug_loc; + + return DW_DLV_OK; + +} +static int +_dwarf_get_loclist_count(Dwarf_Debug dbg, + Dwarf_Off loclist_offset, + int *loclist_count, Dwarf_Error * error) +{ + int count = 0; + Dwarf_Off offset = loclist_offset; + + + for (;;) { + Dwarf_Block b; + Dwarf_Addr lowpc; + Dwarf_Addr highpc; + int res = _dwarf_read_loc_section(dbg, &b, + + &lowpc, &highpc, + offset, error); + + if (res != DW_DLV_OK) { + return res; + } + offset = b.bl_len + b.bl_section_offset; + if (lowpc == 0 && highpc == 0) { + break; + } + count++; + } + *loclist_count = count; + return DW_DLV_OK; +} + +/* Helper routine to avoid code duplication. +*/ +static int +_dwarf_setup_loc(Dwarf_Attribute attr, + Dwarf_Debug * dbg_ret, + Dwarf_Half * form_ret, Dwarf_Error * error) +{ + Dwarf_Debug dbg = 0; + Dwarf_Half form = 0; + int blkres; + + if (attr == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); + return (DW_DLV_ERROR); + } + if (attr->ar_cu_context == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); + return (DW_DLV_ERROR); + } + + dbg = attr->ar_cu_context->cc_dbg; + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); + return (DW_DLV_ERROR); + } + *dbg_ret = dbg; + blkres = dwarf_whatform(attr, &form, error); + if (blkres != DW_DLV_OK) { + _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD); + return blkres; + } + *form_ret = form; + + return DW_DLV_OK; +} + +/* Helper routine to avoid code duplication. +*/ +static int +_dwarf_get_loclist_header_start(Dwarf_Debug dbg, + Dwarf_Attribute attr, + Dwarf_Unsigned * loclist_offset, + Dwarf_Error * error) +{ + int secload = 0; + int blkres = dwarf_formudata(attr, loclist_offset, error); + + if (blkres != DW_DLV_OK) { + return (blkres); + } + + if (!dbg->de_debug_loc) { + secload = _dwarf_load_section(dbg, + dbg->de_debug_loc_index, + &dbg->de_debug_loc, error); + if (secload != DW_DLV_OK) { + return secload; + } + } + return DW_DLV_OK; +} + +/* When llbuf (see dwarf_loclist_n) is partially set up + and an error is encountered, tear it down as it + won't be used. +*/ +static void +_dwarf_cleanup_llbuf(Dwarf_Debug dbg, Dwarf_Locdesc ** llbuf, int count) +{ + int i; + + for (i = 0; i < count; ++i) { + dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK); + dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC); + } + dwarf_dealloc(dbg, llbuf, DW_DLA_LIST); +} + +/* + Handles simple location entries and loclists. + Returns all the Locdesc's thru llbuf. + +*/ +int +dwarf_loclist_n(Dwarf_Attribute attr, + Dwarf_Locdesc *** llbuf_out, + Dwarf_Signed * listlen_out, Dwarf_Error * error) +{ + Dwarf_Debug dbg; + + /* + Dwarf_Attribute that describes the DW_AT_location in die, if + present. */ + Dwarf_Attribute loc_attr = attr; + + /* Dwarf_Block that describes a single location expression. */ + Dwarf_Block loc_block; + + /* A pointer to the current Dwarf_Locdesc read. */ + Dwarf_Locdesc *locdesc = 0; + + Dwarf_Half form = 0; + Dwarf_Addr lowpc = 0; + Dwarf_Addr highpc = 0; + Dwarf_Signed listlen = 0; + Dwarf_Locdesc **llbuf = 0; + + int blkres; + int setup_res; + + /* ***** BEGIN CODE ***** */ + setup_res = _dwarf_setup_loc(attr, &dbg, &form, error); + if (setup_res != DW_DLV_OK) { + return setup_res; + } + /* If this is a form_block then it's a location expression. If it's + DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */ + if (form == DW_FORM_data4 || form == DW_FORM_data8) { + + /* A reference to .debug_loc, with an offset in .debug_loc of a + loclist */ + Dwarf_Unsigned loclist_offset = 0; + int off_res; + int count_res; + int loclist_count; + int lli; + + off_res = _dwarf_get_loclist_header_start(dbg, + attr, &loclist_offset, + error); + if (off_res != DW_DLV_OK) { + return off_res; + } + count_res = _dwarf_get_loclist_count(dbg, loclist_offset, + &loclist_count, error); + listlen = loclist_count; + if (count_res != DW_DLV_OK) { + return count_res; + } + if (loclist_count == 0) { + return DW_DLV_NO_ENTRY; + } + + llbuf = (Dwarf_Locdesc **) + _dwarf_get_alloc(dbg, DW_DLA_LIST, loclist_count); + if (!llbuf) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + for (lli = 0; lli < loclist_count; ++lli) { + blkres = _dwarf_read_loc_section(dbg, &loc_block, + &lowpc, + &highpc, + loclist_offset, error); + if (blkres != DW_DLV_OK) { + _dwarf_cleanup_llbuf(dbg, llbuf, lli); + return (blkres); + } + locdesc = _dwarf_get_locdesc(dbg, &loc_block, + lowpc, highpc, error); + if (locdesc == NULL) { + _dwarf_cleanup_llbuf(dbg, llbuf, lli); + /* low level error already set: let it be passed back */ + return (DW_DLV_ERROR); + } + llbuf[lli] = locdesc; + + /* Now get to next loclist entry offset. */ + loclist_offset = loc_block.bl_section_offset + + loc_block.bl_len; + } + + + } else { + Dwarf_Block *tblock = 0; + + blkres = dwarf_formblock(loc_attr, &tblock, error); + if (blkres != DW_DLV_OK) { + return (blkres); + } + loc_block = *tblock; + /* We copied tblock contents to the stack var, so can dealloc + tblock now. Avoids leaks. */ + dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK); + listlen = 1; /* One by definition of a location + entry. */ + lowpc = 0; /* HACK */ + highpc = (Dwarf_Unsigned) (-1LL); /* HACK */ + + /* An empty location description (block length 0) means the + code generator emitted no variable, the variable was not + generated, it was unused or perhaps never tested after being + set. Dwarf2, section 2.4.1 In other words, it is not an + error, and we don't test for block length 0 specially here. */ + locdesc = _dwarf_get_locdesc(dbg, &loc_block, + lowpc, highpc, error); + if (locdesc == NULL) { + /* low level error already set: let it be passed back */ + return (DW_DLV_ERROR); + } + llbuf = (Dwarf_Locdesc **) + _dwarf_get_alloc(dbg, DW_DLA_LIST, listlen); + if (!llbuf) { + /* Free the locdesc we allocated but won't use. */ + dwarf_dealloc(dbg, locdesc, DW_DLA_LOCDESC); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + llbuf[0] = locdesc; + } + + *llbuf_out = llbuf; + *listlen_out = listlen; + return (DW_DLV_OK); +} + + +/* + Handles only a location expression. + If called on a loclist, just returns one of those. + Cannot not handle a real loclist. + It returns the location expression as a loclist with + a single entry. + See dwarf_loclist_n() which handles any number + of location list entries. + + This is the original definition, and it simply + does not work for loclists. Kept for compatibility. +*/ +int +dwarf_loclist(Dwarf_Attribute attr, + Dwarf_Locdesc ** llbuf, + Dwarf_Signed * listlen, Dwarf_Error * error) +{ + Dwarf_Debug dbg; + + /* + Dwarf_Attribute that describes the DW_AT_location in die, if + present. */ + Dwarf_Attribute loc_attr = attr; + + /* Dwarf_Block that describes a single location expression. */ + Dwarf_Block loc_block; + + /* A pointer to the current Dwarf_Locdesc read. */ + Dwarf_Locdesc *locdesc = 0; + + Dwarf_Half form = 0; + Dwarf_Addr lowpc = 0; + Dwarf_Addr highpc = 0; + + int blkres; + int setup_res; + + /* ***** BEGIN CODE ***** */ + setup_res = _dwarf_setup_loc(attr, &dbg, &form, error); + if (setup_res != DW_DLV_OK) { + return setup_res; + } + /* If this is a form_block then it's a location expression. If it's + DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */ + if (form == DW_FORM_data4 || form == DW_FORM_data8) { + + /* A reference to .debug_loc, with an offset in .debug_loc of a + loclist */ + Dwarf_Unsigned loclist_offset = 0; + int off_res; + + off_res = _dwarf_get_loclist_header_start(dbg, + attr, &loclist_offset, + error); + if (off_res != DW_DLV_OK) { + return off_res; + } + + /* With dwarf_loclist, just read a single entry */ + blkres = _dwarf_read_loc_section(dbg, &loc_block, + &lowpc, + &highpc, + loclist_offset, error); + if (blkres != DW_DLV_OK) { + return (blkres); + } + + + + + } else { + Dwarf_Block *tblock = 0; + + blkres = dwarf_formblock(loc_attr, &tblock, error); + if (blkres != DW_DLV_OK) { + return (blkres); + } + loc_block = *tblock; + /* We copied tblock contents to the stack var, so can dealloc + tblock now. Avoids leaks. */ + dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK); + lowpc = 0; /* HACK */ + highpc = (Dwarf_Unsigned) (-1LL); /* HACK */ + } + + /* An empty location description (block length 0) means the code + generator emitted no variable, the variable was not generated, + it was unused or perhaps never tested after being set. Dwarf2, + section 2.4.1 In other words, it is not an error, and we don't + test for block length 0 specially here. FIXME: doing this once + is wrong, needs to handle low/hi pc sets. */ + locdesc = _dwarf_get_locdesc(dbg, &loc_block, lowpc, highpc, error); + if (locdesc == NULL) { + /* low level error already set: let it be passed back */ + return (DW_DLV_ERROR); + } + + *llbuf = locdesc; + *listlen = 1; + return (DW_DLV_OK); +} + + + +/* + Handles only a location expression. + It returns the location expression as a loclist with + a single entry. + + Usable to access dwarf expressions from any source, but + specifically from + DW_CFA_def_cfa_expression + DW_CFA_expression + DW_CFA_val_expression + + expression_in must point to a valid dwarf expression + set of bytes of length expression_length. Not + a DW_FORM_block*, just the expression bytes. + +*/ +int +dwarf_loclist_from_expr(Dwarf_Debug dbg, + Dwarf_Ptr expression_in, + Dwarf_Unsigned expression_length, + Dwarf_Locdesc ** llbuf, + Dwarf_Signed * listlen, Dwarf_Error * error) +{ + /* Dwarf_Block that describes a single location expression. */ + Dwarf_Block loc_block; + + /* A pointer to the current Dwarf_Locdesc read. */ + Dwarf_Locdesc *locdesc = 0; + Dwarf_Addr lowpc = 0; + Dwarf_Addr highpc = (Dwarf_Unsigned) (-1LL); + + memset(&loc_block,0,sizeof(loc_block)); + loc_block.bl_len = expression_length; + loc_block.bl_data = expression_in; + loc_block.bl_from_loclist = 0; /* Not from loclist. */ + loc_block.bl_section_offset = 0; /* Fake. Not meaningful. */ + + + /* An empty location description (block length 0) means the code + generator emitted no variable, the variable was not generated, + it was unused or perhaps never tested after being set. Dwarf2, + section 2.4.1 In other words, it is not an error, and we don't + test for block length 0 specially here. */ + locdesc = _dwarf_get_locdesc(dbg, &loc_block, lowpc, highpc, error); + if (locdesc == NULL) { + /* low level error already set: let it be passed back */ + return (DW_DLV_ERROR); + } + + *llbuf = locdesc; + *listlen = 1; + return (DW_DLV_OK); +} + +/* Usable to read a single loclist or to read a block of them + or to read an entire section's loclists. + +*/ + + /*ARGSUSED*/ int +dwarf_get_loclist_entry(Dwarf_Debug dbg, + Dwarf_Unsigned offset, + Dwarf_Addr * hipc_offset, + Dwarf_Addr * lopc_offset, + Dwarf_Ptr * data, + Dwarf_Unsigned * entry_len, + Dwarf_Unsigned * next_entry, + Dwarf_Error * error) +{ + Dwarf_Block b; + Dwarf_Addr lowpc; + Dwarf_Addr highpc; + int res; + + if (!dbg->de_debug_loc) { + int secload = _dwarf_load_section(dbg, + dbg->de_debug_loc_index, + &dbg->de_debug_loc, + error); + + if (secload != DW_DLV_OK) { + return secload; + } + } + + res = _dwarf_read_loc_section(dbg, + &b, &lowpc, &highpc, offset, error); + if (res != DW_DLV_OK) { + return res; + } + *hipc_offset = highpc; + *lopc_offset = lowpc; + *entry_len = b.bl_len; + *data = b.bl_data; + *next_entry = b.bl_len + b.bl_section_offset; + + return DW_DLV_OK; + + + +} + + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_loc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_loc.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,46 @@ +/* + + Copyright (C) 2000, 2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +typedef struct Dwarf_Loc_Chain_s *Dwarf_Loc_Chain; + +struct Dwarf_Loc_Chain_s { + Dwarf_Small lc_atom; + Dwarf_Unsigned lc_number; + Dwarf_Unsigned lc_number2; + Dwarf_Unsigned lc_offset; + Dwarf_Loc_Chain lc_next; +}; diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_macro.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_macro.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,473 @@ +/* + + Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include +#ifdef HAVE_STDLIB_H +#include +#endif /* HAVE_STDLIB_H */ +#include "dwarf_macro.h" + + +#define LEFTPAREN '(' +#define RIGHTPAREN ')' +#define SPACE ' ' + +/* + Given the dwarf macro string, return a pointer to + the value. Returns pointer to 0 byte at end of string + if no value found (meaning the value is the empty string). + + Only understands well-formed dwarf macinfo strings. +*/ +char * +dwarf_find_macro_value_start(char *str) +{ + char *lcp; + int funclike = 0; + + for (lcp = str; *lcp; ++lcp) { + switch (*lcp) { + case LEFTPAREN: + funclike = 1; + break; + case RIGHTPAREN: + /* lcp+1 must be a space, and following char is the value */ + return lcp + 2; + case SPACE: + /* we allow extraneous spaces inside macro parameter ** + list, just in case... This is not really needed. */ + if (!funclike) { + return lcp + 1; + } + break; + } + } + /* never found value: returns pointer to the 0 byte at end of + string */ + return lcp; + +} + + +/* + Try to keep fileindex correct in every Macro_Details + record by tracking file starts and ends. + Uses high water mark: space reused, not freed. + Presumption is that this makes sense for most uses. + STARTERMAX is set so that the array need not be expanded for + most files: it is the initial include file depth. +*/ +struct macro_stack_s { + Dwarf_Signed *st_base; + long max; + long next_to_use; + int was_fault; +}; + +static void _dwarf_reset_index_macro_stack(struct macro_stack_s *ms); +static void +free_macro_stack(Dwarf_Debug dbg, struct macro_stack_s *ms) +{ + dwarf_dealloc(dbg,ms->st_base,DW_DLA_STRING); + _dwarf_reset_index_macro_stack(ms); +} + +#define STARTERMAX 10 +static void +_dwarf_reset_index_macro_stack(struct macro_stack_s *ms) +{ + ms->st_base = 0; + ms->max = 0; + ms->next_to_use = 0; + ms->was_fault = 0; +} +static int +_dwarf_macro_stack_push_index(Dwarf_Debug dbg, Dwarf_Signed indx, + struct macro_stack_s *ms) +{ + Dwarf_Signed *newbase; + + if (ms->next_to_use >= ms->max) { + long new_size; + + if (ms->max == 0) { + ms->max = STARTERMAX; + } + new_size = ms->max * 2; + newbase = + _dwarf_get_alloc(dbg, DW_DLA_STRING, + new_size * sizeof(Dwarf_Signed)); + if (newbase == 0) { + /* just leave the old array in place */ + ms->was_fault = 1; + return DW_DLV_ERROR; + } + if(ms->st_base) { + memcpy(newbase, ms->st_base, + ms->next_to_use * sizeof(Dwarf_Signed)); + dwarf_dealloc(dbg, ms->st_base, DW_DLA_STRING); + } + ms->st_base = newbase; + ms->max = new_size; + } + ms->st_base[ms->next_to_use] = indx; + ++ms->next_to_use; + return DW_DLV_OK; +} + +static Dwarf_Signed +_dwarf_macro_stack_pop_index(struct macro_stack_s *ms) +{ + if (ms->was_fault) { + return -1; + } + if (ms->next_to_use > 0) { + ms->next_to_use--; + return (ms->st_base[ms->next_to_use]); + } else { + ms->was_fault = 1; + } + return -1; +} + +/* starting at macro_offset in .debug_macinfo, + if maximum_count is 0, treat as if it is infinite. + get macro data up thru + maximum_count entries or the end of a compilation + unit's entries (whichever comes first). +*/ + +int +dwarf_get_macro_details(Dwarf_Debug dbg, + Dwarf_Off macro_offset, + Dwarf_Unsigned maximum_count, + Dwarf_Signed * entry_count, + Dwarf_Macro_Details ** details, + Dwarf_Error * error) +{ + Dwarf_Small *macro_base = 0; + Dwarf_Small *pnext = 0; + Dwarf_Unsigned endloc = 0; + unsigned char uc = 0; + unsigned long depth = 0; /* By section 6.3.2 Dwarf3 draft 8/9, + the base file should appear as + DW_MACINFO_start_file. See + http://gcc.gnu.org/ml/gcc-bugs/2005-02/msg03442.html + on "[Bug debug/20253] New: [3.4/4.0 regression]: + Macro debug info broken due to lexer change" for how + gcc is broken in some versions. We no longer use + depth as a stopping point, it's not needed as a + stopping point anyway. */ + + + int res = 0; + + /* count space used by strings */ + unsigned long str_space = 0; + int done = 0; + unsigned long space_needed = 0; + unsigned long string_offset = 0; + Dwarf_Small *return_data = 0; + Dwarf_Small *pdata = 0; + unsigned long final_count = 0; + Dwarf_Signed fileindex = -1; + Dwarf_Small *latest_str_loc = 0; + struct macro_stack_s msdata; + + unsigned long count = 0; + unsigned long max_count = (unsigned long) maximum_count; + + _dwarf_reset_index_macro_stack(&msdata); + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + free_macro_stack(dbg,&msdata); + return (DW_DLV_ERROR); + } + + res = + _dwarf_load_section(dbg, + dbg->de_debug_macinfo_index, + &dbg->de_debug_macinfo, error); + if (res != DW_DLV_OK) { + free_macro_stack(dbg,&msdata); + return res; + } + + macro_base = dbg->de_debug_macinfo; + if (macro_base == NULL) { + free_macro_stack(dbg,&msdata); + return (DW_DLV_NO_ENTRY); + } + if (macro_offset >= dbg->de_debug_macinfo_size) { + free_macro_stack(dbg,&msdata); + return (DW_DLV_NO_ENTRY); + } + + pnext = macro_base + macro_offset; + if (maximum_count == 0) { + max_count = ULONG_MAX; + } + + + /* how many entries and how much space will they take? */ + + endloc = (pnext - macro_base); + if (endloc >= dbg->de_debug_macinfo_size) { + if (endloc == dbg->de_debug_macinfo_size) { + /* normal: found last entry */ + free_macro_stack(dbg,&msdata); + return DW_DLV_NO_ENTRY; + } + _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD); + free_macro_stack(dbg,&msdata); + return (DW_DLV_ERROR); + } + for (count = 0; !done && count < max_count; ++count) { + unsigned long slen; + Dwarf_Word len; + + uc = *pnext; + ++pnext; /* get past the type code */ + switch (uc) { + case DW_MACINFO_define: + case DW_MACINFO_undef: + /* line, string */ + case DW_MACINFO_vendor_ext: + /* number, string */ + (void) _dwarf_decode_u_leb128(pnext, &len); + + pnext += len; + if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) { + free_macro_stack(dbg,&msdata); + _dwarf_error(dbg, error, + DW_DLE_DEBUG_MACRO_INCONSISTENT); + return (DW_DLV_ERROR); + } + slen = strlen((char *) pnext) + 1; + pnext += slen; + if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) { + free_macro_stack(dbg,&msdata); + _dwarf_error(dbg, error, + DW_DLE_DEBUG_MACRO_INCONSISTENT); + return (DW_DLV_ERROR); + } + str_space += slen; + break; + case DW_MACINFO_start_file: + /* line, file index */ + (void) _dwarf_decode_u_leb128(pnext, &len); + pnext += len; + if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) { + free_macro_stack(dbg,&msdata); + _dwarf_error(dbg, error, + DW_DLE_DEBUG_MACRO_INCONSISTENT); + return (DW_DLV_ERROR); + } + (void) _dwarf_decode_u_leb128(pnext, &len); + pnext += len; + if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) { + free_macro_stack(dbg,&msdata); + _dwarf_error(dbg, error, + DW_DLE_DEBUG_MACRO_INCONSISTENT); + return (DW_DLV_ERROR); + } + ++depth; + break; + + case DW_MACINFO_end_file: + if (--depth == 0) { + /* done = 1; no, do not stop here, at least one gcc had + the wrong depth settings in the gcc 3.4 timeframe. */ + } + break; /* no string or number here */ + case 0: + /* end of cu's entries */ + done = 1; + break; + default: + free_macro_stack(dbg,&msdata); + _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); + return (DW_DLV_ERROR); + /* bogus macinfo! */ + } + + endloc = (pnext - macro_base); + if (endloc == dbg->de_debug_macinfo_size) { + done = 1; + } else if (endloc > dbg->de_debug_macinfo_size) { + _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD); + free_macro_stack(dbg,&msdata); + return (DW_DLV_ERROR); + } + } + if (count == 0) { + free_macro_stack(dbg,&msdata); + _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INTERNAL_ERR); + return (DW_DLV_ERROR); + } + + /* we have 'count' array entries to allocate and str_space bytes of + string space to provide for. */ + + string_offset = count * sizeof(Dwarf_Macro_Details); + + /* extra 2 not really needed */ + space_needed = string_offset + str_space + 2; + return_data = pdata = + _dwarf_get_alloc(dbg, DW_DLA_STRING, space_needed); + latest_str_loc = pdata + string_offset; + if (pdata == 0) { + free_macro_stack(dbg,&msdata); + _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_MALLOC_SPACE); + return (DW_DLV_ERROR); + } + pnext = macro_base + macro_offset; + + done = 0; + + /* A series ends with a type code of 0. */ + + for (final_count = 0; !done && final_count < count; ++final_count) { + unsigned long slen; + Dwarf_Word len; + Dwarf_Unsigned v1; + Dwarf_Macro_Details *pdmd = (Dwarf_Macro_Details *) (pdata + + (final_count * sizeof (Dwarf_Macro_Details))); + + endloc = (pnext - macro_base); + if (endloc > dbg->de_debug_macinfo_size) { + free_macro_stack(dbg,&msdata); + _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD); + return (DW_DLV_ERROR); + } + uc = *pnext; + pdmd->dmd_offset = (pnext - macro_base); + pdmd->dmd_type = uc; + pdmd->dmd_fileindex = fileindex; + pdmd->dmd_lineno = 0; + pdmd->dmd_macro = 0; + ++pnext; /* get past the type code */ + switch (uc) { + case DW_MACINFO_define: + case DW_MACINFO_undef: + /* line, string */ + case DW_MACINFO_vendor_ext: + /* number, string */ + v1 = _dwarf_decode_u_leb128(pnext, &len); + pdmd->dmd_lineno = v1; + + pnext += len; + if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) { + free_macro_stack(dbg,&msdata); + dwarf_dealloc(dbg, return_data, DW_DLA_STRING); + _dwarf_error(dbg, error, + DW_DLE_DEBUG_MACRO_INCONSISTENT); + return (DW_DLV_ERROR); + } + slen = strlen((char *) pnext) + 1; + strcpy((char *) latest_str_loc, (char *) pnext); + pdmd->dmd_macro = (char *) latest_str_loc; + latest_str_loc += slen; + pnext += slen; + if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) { + free_macro_stack(dbg,&msdata); + dwarf_dealloc(dbg, return_data, DW_DLA_STRING); + _dwarf_error(dbg, error, + DW_DLE_DEBUG_MACRO_INCONSISTENT); + return (DW_DLV_ERROR); + } + break; + case DW_MACINFO_start_file: + /* Line, file index */ + v1 = _dwarf_decode_u_leb128(pnext, &len); + pdmd->dmd_lineno = v1; + pnext += len; + if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) { + free_macro_stack(dbg,&msdata); + dwarf_dealloc(dbg, return_data, DW_DLA_STRING); + _dwarf_error(dbg, error, + DW_DLE_DEBUG_MACRO_INCONSISTENT); + return (DW_DLV_ERROR); + } + v1 = _dwarf_decode_u_leb128(pnext, &len); + pdmd->dmd_fileindex = v1; + (void) _dwarf_macro_stack_push_index(dbg, fileindex, + &msdata); + /* We ignore the error, we just let fileindex ** be -1 when + we pop this one. */ + fileindex = v1; + pnext += len; + if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) { + free_macro_stack(dbg,&msdata); + dwarf_dealloc(dbg, return_data, DW_DLA_STRING); + _dwarf_error(dbg, error, + DW_DLE_DEBUG_MACRO_INCONSISTENT); + return (DW_DLV_ERROR); + } + break; + + case DW_MACINFO_end_file: + fileindex = _dwarf_macro_stack_pop_index(&msdata); + break; /* no string or number here */ + case 0: + /* Type code of 0 means the end of cu's entries. */ + done = 1; + break; + default: + /* Bogus macinfo! */ + dwarf_dealloc(dbg, return_data, DW_DLA_STRING); + free_macro_stack(dbg,&msdata); + _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); + return (DW_DLV_ERROR); + } + } + *entry_count = count; + *details = (Dwarf_Macro_Details *) return_data; + + free_macro_stack(dbg,&msdata); + return DW_DLV_OK; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_macro.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_macro.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,44 @@ +/* + + Copyright (C) 2000, 2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + +/* + + + dwarf_macro.h + + $Revision: 1.4 $ $Date: 2004/10/28 22:19:14 $ + +*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_opaque.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_opaque.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,301 @@ +/* + + Copyright (C) 2000,2002,2003,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The versions applicable by section are: + DWARF2 DWARF3 DWARF4 + .debug_info 2 3 4 + .debug_abbrev - - - + .debug_frame 1 3 3 + .debug_str - - - + .debug_loc - - - + .debug_line 2 3 3 + .debug_aranges 2 2 2 + .debug_ranges x - - + .debug_pubtypes x 2 2 + .debug_pubnames 2 2 2 + .debug_macinfo - - - +*/ + +#include + + +struct Dwarf_Die_s { + /* + Points to the start of the portion corresponding to this Die in + the .debug_info section. */ + Dwarf_Byte_Ptr di_debug_info_ptr; + + Dwarf_Abbrev_List di_abbrev_list; + + /* Points to cu context for this die. */ + Dwarf_CU_Context di_cu_context; +}; + +struct Dwarf_Attribute_s { + Dwarf_Half ar_attribute; /* Attribute Value. */ + Dwarf_Half ar_attribute_form; /* Attribute Form. */ + Dwarf_Half ar_attribute_form_direct; + /* Identical to ar_attribute_form except that if + the original form uleb was DW_FORM_indirect, + ar_attribute_form_direct contains DW_FORM_indirect + but ar_attribute_form contains the true form. */ + + Dwarf_CU_Context ar_cu_context; + Dwarf_Small *ar_debug_info_ptr; + Dwarf_Attribute ar_next; +}; + +/* + This structure provides the context for a compilation unit. + Thus, it contains the Dwarf_Debug, cc_dbg, that this cu + belongs to. It contains the information in the compilation + unit header, cc_length, cc_version_stamp, cc_abbrev_offset, + and cc_address_size, in the .debug_info section for that cu. + In addition, it contains the count, cc_count_cu, of the cu + number of that cu in the list of cu's in the .debug_info. + The count starts at 1, ie cc_count_cu is 1 for the first cu, + 2 for the second and so on. This struct also contains a + pointer, cc_abbrev_table, to a list of pairs of abbrev code + and a pointer to the start of that abbrev + in the .debug_abbrev section. + + Each die will also contain a pointer to such a struct to + record the context for that die. + + **Updated by dwarf_next_cu_header in dwarf_die_deliv.c +*/ +struct Dwarf_CU_Context_s { + Dwarf_Debug cc_dbg; + Dwarf_Word cc_length; + Dwarf_Small cc_length_size; + Dwarf_Small cc_extension_size; + Dwarf_Half cc_version_stamp; + Dwarf_Sword cc_abbrev_offset; + Dwarf_Small cc_address_size; + Dwarf_Word cc_debug_info_offset; + Dwarf_Byte_Ptr cc_last_abbrev_ptr; + Dwarf_Hash_Table cc_abbrev_hash_table; + Dwarf_CU_Context cc_next; + unsigned char cc_offset_length; +}; + + +struct Dwarf_Debug_s { + dwarf_elf_handle de_elf; /* see de_elf_must_close at end of struct */ + + Dwarf_Unsigned de_access; + Dwarf_Handler de_errhand; + Dwarf_Ptr de_errarg; + + /* + Context for the compilation_unit just read by a call to + dwarf_next_cu_header. **Updated by dwarf_next_cu_header in + dwarf_die_deliv.c */ + Dwarf_CU_Context de_cu_context; + + /* + Points to linked list of CU Contexts for the CU's already read. + These are only CU's read by dwarf_next_cu_header(). */ + Dwarf_CU_Context de_cu_context_list; + + /* + Points to the last CU Context added to the list by + dwarf_next_cu_header(). */ + Dwarf_CU_Context de_cu_context_list_end; + + /* + This is the list of CU contexts read for dwarf_offdie(). These + may read ahead of dwarf_next_cu_header(). */ + Dwarf_CU_Context de_offdie_cu_context; + Dwarf_CU_Context de_offdie_cu_context_end; + + /* Offset of last byte of last CU read. */ + Dwarf_Word de_info_last_offset; + + /* + Number of bytes in the length, and offset field in various + .debug_* sections. It's not very meaningful, and is + only used in one 'approximate' calculation. */ + Dwarf_Small de_length_size; + + /* number of bytes in a pointer of the target in various .debug_ + sections. 4 in 32bit, 8 in MIPS 64, ia64. */ + Dwarf_Small de_pointer_size; + + /* set at creation of a Dwarf_Debug to say if form_string should be + checked for valid length at every call. 0 means do the check. + non-zero means do not do the check. */ + Dwarf_Small de_assume_string_in_bounds; + + /* + Dwarf_Alloc_Hdr_s structs used to manage chunks that are + malloc'ed for each allocation type for structs. */ + struct Dwarf_Alloc_Hdr_s de_alloc_hdr[ALLOC_AREA_REAL_TABLE_MAX]; +#ifdef DWARF_SIMPLE_MALLOC + struct simple_malloc_record_s * de_simple_malloc_base; +#endif + + + /* + These fields are used to process debug_frame section. **Updated + by dwarf_get_fde_list in dwarf_frame.h */ + /* + Points to contiguous block of pointers to Dwarf_Cie_s structs. */ + Dwarf_Cie *de_cie_data; + /* Count of number of Dwarf_Cie_s structs. */ + Dwarf_Signed de_cie_count; + /* + Points to contiguous block of pointers to Dwarf_Fde_s structs. */ + Dwarf_Fde *de_fde_data; + /* Count of number of Dwarf_Fde_s structs. */ + Dwarf_Signed de_fde_count; + + Dwarf_Small *de_debug_info; + Dwarf_Small *de_debug_abbrev; + Dwarf_Small *de_debug_line; + Dwarf_Small *de_debug_loc; + Dwarf_Small *de_debug_aranges; + Dwarf_Small *de_debug_macinfo; + Dwarf_Small *de_debug_pubnames; + Dwarf_Small *de_debug_str; + Dwarf_Small *de_debug_frame; + Dwarf_Small *de_debug_pubtypes; /* DWARF3 .debug_pubtypes */ + Dwarf_Small *de_debug_frame_eh_gnu; /* gnu for the g++ eh_frame + section */ + Dwarf_Addr de_debug_frame_eh_addr; /* gnu for the g++ eh_frame + section. Section address + from Elf. Purpose: to handle + DW_EH_PE_pcrel encoding. */ + + Dwarf_Small *de_debug_funcnames; + Dwarf_Small *de_debug_typenames; /* SGI IRIX extension essentially + identical to DWARF3 .debug_pubtypes. */ + Dwarf_Small *de_debug_varnames; + Dwarf_Small *de_debug_weaknames; + + Dwarf_Unsigned de_debug_info_size; + Dwarf_Unsigned de_debug_abbrev_size; + Dwarf_Unsigned de_debug_line_size; + Dwarf_Unsigned de_debug_loc_size; + Dwarf_Unsigned de_debug_aranges_size; + Dwarf_Unsigned de_debug_macinfo_size; + Dwarf_Unsigned de_debug_pubnames_size; + Dwarf_Unsigned de_debug_str_size; + Dwarf_Unsigned de_debug_pubtypes_size; /* DWARF3 .debug_pubtypes*/ + + + Dwarf_Unsigned de_debug_frame_size; + + Dwarf_Unsigned de_debug_frame_size_eh_gnu; /* gnu for the g++ + eh_frame section */ + + Dwarf_Unsigned de_debug_funcnames_size; + Dwarf_Unsigned de_debug_typenames_size; + Dwarf_Unsigned de_debug_varnames_size; + Dwarf_Unsigned de_debug_weaknames_size; + + void *(*de_copy_word) (void *, const void *, size_t); + unsigned char de_same_endian; + unsigned char de_elf_must_close; /* if non-zero, then + it was dwarf_init (not dwarf_elf_init) + so must elf_end() */ + + /* + The following are used for storing section indicies. + + After a Dwarf_Debug is initialized, a zero for any of + these indicies indicates an absent section. + + If the ELF spec is ever changed to permit 32-bit section + indicies, these will need to be changed. + */ + Dwarf_Half de_debug_aranges_index; + Dwarf_Half de_debug_line_index; + Dwarf_Half de_debug_loc_index; + Dwarf_Half de_debug_macinfo_index; + Dwarf_Half de_debug_pubnames_index; + Dwarf_Half de_debug_funcnames_index; + Dwarf_Half de_debug_typenames_index; + Dwarf_Half de_debug_varnames_index; + Dwarf_Half de_debug_weaknames_index; + Dwarf_Half de_debug_frame_index; + Dwarf_Half de_debug_frame_eh_gnu_index; + Dwarf_Half de_debug_str_index; + Dwarf_Half de_debug_info_index; + Dwarf_Half de_debug_abbrev_index; + Dwarf_Half de_debug_pubtypes_index; /* DWARF3 .debug_pubtypes */ + + /* Default is DW_FRAME_INITIAL_VALUE from header. */ + Dwarf_Half de_frame_rule_initial_value; + + /* Default is DW_FRAME_LAST_REG_NUM. */ + Dwarf_Half de_frame_reg_rules_entry_count; + + + unsigned char de_big_endian_object; /* non-zero if big-endian + object opened. */ +}; + +typedef struct Dwarf_Chain_s *Dwarf_Chain; +struct Dwarf_Chain_s { + void *ch_item; + Dwarf_Chain ch_next; +}; + + +#define CURRENT_VERSION_STAMP 2 /* DWARF2 */ +#define CURRENT_VERSION_STAMP3 3 /* DWARF3 */ +#define CURRENT_VERSION_STAMP4 3 /* DWARF4 */ + + /* Size of cu header version stamp field. */ +#define CU_VERSION_STAMP_SIZE sizeof(Dwarf_Half) + + /* Size of cu header address size field. */ +#define CU_ADDRESS_SIZE_SIZE sizeof(Dwarf_Small) + +void *_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len); + +#define ORIGINAL_DWARF_OFFSET_SIZE 4 +#define DISTINGUISHED_VALUE 0xffffffff +#define DISTINGUISHED_VALUE_OFFSET_SIZE 8 + +/* + We don't load the sections until they are needed. This function is + used to load the section. + */ +int _dwarf_load_section(Dwarf_Debug, + Dwarf_Half, + Dwarf_Small **, + Dwarf_Error *); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_print_lines.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_print_lines.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,655 @@ +/* + + Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include +#include "dwarf_line.h" +#ifdef HAVE_ALLOCA_H +#include +#endif + +/* FIXME Need to add prologue_end epilogue_begin isa fields. */ +static void +print_line_header(void) +{ + printf + (" s b e\n" + " t l s\n" + " m c e\n" + " section op col t k q\n" + " offset code address file line umn ? ? ?\n"); +} + +/* FIXME: print new line values: prologue_end epilogue_begin isa */ +static void +print_line_detail(char *prefix, + int opcode, + unsigned long long address, + unsigned long file, + unsigned long line, + unsigned long column, + int is_stmt, int basic_block, int end_sequence, + int prologue_end, int epilogue_begin, int isa) +{ + printf("%-15s %2d 0x%08llx " + "%2lu %4lu %2lu %1d %1d %1d\n", + prefix, + (int) opcode, + (long long) address, + (unsigned long) file, + (unsigned long) line, + (unsigned long) column, + (int) is_stmt, (int) basic_block, (int) end_sequence); + +} + + +/* + return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR +*/ +int +_dwarf_internal_printlines(Dwarf_Die die, Dwarf_Error * error) +{ + /* + This pointer is used to scan the portion of the .debug_line + section for the current cu. */ + Dwarf_Small *line_ptr; + Dwarf_Small *orig_line_ptr; + + /* + This points to the last byte of the .debug_line portion for the + current cu. */ + Dwarf_Small *line_ptr_end = 0; + + /* + Pointer to a DW_AT_stmt_list attribute in case it exists in the + die. */ + Dwarf_Attribute stmt_list_attr; + + /* Pointer to DW_AT_comp_dir attribute in die. */ + Dwarf_Attribute comp_dir_attr; + + /* Pointer to name of compilation directory. */ + Dwarf_Small *comp_dir = NULL; + + /* + Offset into .debug_line specified by a DW_AT_stmt_list + attribute. */ + Dwarf_Unsigned line_offset; + + struct Line_Table_Prefix_s prefix; + + + /* These are the state machine state variables. */ + Dwarf_Addr address = 0; + Dwarf_Word file = 1; + Dwarf_Word line = 1; + Dwarf_Word column = 0; + Dwarf_Bool is_stmt = false; + Dwarf_Bool basic_block = false; + Dwarf_Bool end_sequence = false; + Dwarf_Bool prologue_end = false; + Dwarf_Bool epilogue_begin = false; + Dwarf_Small isa = 0; + + + Dwarf_Sword i; + + /* + This is the current opcode read from the statement program. */ + Dwarf_Small opcode; + + + /* + These variables are used to decode leb128 numbers. Leb128_num + holds the decoded number, and leb128_length is its length in + bytes. */ + Dwarf_Word leb128_num; + Dwarf_Word leb128_length; + Dwarf_Sword advance_line; + + /* + This is the operand of the latest fixed_advance_pc extended + opcode. */ + Dwarf_Half fixed_advance_pc; + + + /* The Dwarf_Debug this die belongs to. */ + Dwarf_Debug dbg; + int resattr; + int lres; + + int res; + + /* ***** BEGIN CODE ***** */ + + if (error != NULL) + *error = NULL; + + CHECK_DIE(die, DW_DLV_ERROR); + dbg = die->di_cu_context->cc_dbg; + + res = + _dwarf_load_section(dbg, + dbg->de_debug_line_index, + &dbg->de_debug_line, error); + if (res != DW_DLV_OK) { + return res; + } + + resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error); + if (resattr != DW_DLV_OK) { + return resattr; + } + + + + lres = dwarf_formudata(stmt_list_attr, &line_offset, error); + if (lres != DW_DLV_OK) { + return lres; + } + + if (line_offset >= dbg->de_debug_line_size) { + _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); + return (DW_DLV_ERROR); + } + orig_line_ptr = dbg->de_debug_line; + line_ptr = dbg->de_debug_line + line_offset; + dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); + + /* + If die has DW_AT_comp_dir attribute, get the string that names + the compilation directory. */ + resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error); + if (resattr == DW_DLV_ERROR) { + return resattr; + } + if (resattr == DW_DLV_OK) { + int cres; + char *cdir; + + cres = dwarf_formstring(comp_dir_attr, &cdir, error); + if (cres == DW_DLV_ERROR) { + return cres; + } else if (cres == DW_DLV_OK) { + comp_dir = (Dwarf_Small *) cdir; + } + } + if (resattr == DW_DLV_OK) { + dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR); + } + + dwarf_init_line_table_prefix(&prefix); + { + Dwarf_Small *line_ptr_out = 0; + int dres = dwarf_read_line_table_prefix(dbg, + line_ptr, + dbg-> + de_debug_line_size - + line_offset, + &line_ptr_out, + &prefix, error); + + if (dres == DW_DLV_ERROR) { + dwarf_free_line_table_prefix(&prefix); + return dres; + } + if (dres == DW_DLV_NO_ENTRY) { + dwarf_free_line_table_prefix(&prefix); + return dres; + } + line_ptr_end = prefix.pf_line_ptr_end; + line_ptr = line_ptr_out; + } + + + + printf("total line info length %ld bytes, " + "line offset 0x%llx %lld\n", + (long) prefix.pf_total_length, + (long long) line_offset, (long long) line_offset); + printf("compilation_directory %s\n", + comp_dir ? ((char *) comp_dir) : ""); + + printf(" min instruction length %d\n", + (int) prefix.pf_minimum_instruction_length); + printf(" default is stmt %d\n", (int) + prefix.pf_default_is_stmt); + printf(" line base %d\n", (int) + prefix.pf_line_base); + printf(" line_range %d\n", (int) + prefix.pf_line_range); + + + for (i = 1; i < prefix.pf_opcode_base; i++) { + printf(" opcode[%d] length %d\n", (int) i, + (int) prefix.pf_opcode_length_table[i - 1]); + } + + for (i = 0; i < prefix.pf_include_directories_count; ++i) { + printf(" include dir[%d] %s\n", + (int) i, prefix.pf_include_directories[i]); + } + + + for (i = 0; i < prefix.pf_files_count; ++i) { + struct Line_Table_File_Entry_s *lfile = + prefix.pf_line_table_file_entries + i; + + Dwarf_Unsigned tlm2 = lfile->lte_last_modification_time; + Dwarf_Unsigned di = lfile->lte_directory_index; + Dwarf_Unsigned fl = lfile->lte_length_of_file; + + printf(" file[%d] %s\n", + (int) i, (char *) lfile->lte_filename); + + printf(" dir index %d\n", (int) di); + { + time_t tt = (time_t) tlm2; + + printf(" last time 0x%x %s", /* ctime supplies + newline */ + (unsigned) tlm2, ctime(&tt)); + } + printf(" file length %ld 0x%lx\n", + (long) fl, (unsigned long) fl); + + + } + + + { + unsigned long long offset = line_ptr - orig_line_ptr; + + printf(" statement prog offset in section: %llu 0x%llx\n", + offset, offset); + } + + /* Initialize the part of the state machine dependent on the + prefix. */ + is_stmt = prefix.pf_default_is_stmt; + + + print_line_header(); + /* Start of statement program. */ + while (line_ptr < line_ptr_end) { + int type; + + printf(" [0x%06llx] ", (long long) (line_ptr - orig_line_ptr)); + opcode = *(Dwarf_Small *) line_ptr; + line_ptr++; + /* 'type' is the output */ + WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base, + prefix.pf_opcode_length_table, line_ptr, + prefix.pf_std_op_count); + + if (type == LOP_DISCARD) { + int oc; + int opcnt = prefix.pf_opcode_length_table[opcode]; + + printf(" DISCARD standard opcode %d with %d operands: " + "not understood:", opcode, opcnt); + for (oc = 0; oc < opcnt; oc++) { + /* + * Read and discard operands we don't + * understand. + * Arbitrary choice of unsigned read. + * Signed read would work as well. + */ + Dwarf_Unsigned utmp2; + + DECODE_LEB128_UWORD(line_ptr, utmp2); + printf(" %llu (0x%llx)", + (unsigned long long) utmp2, + (unsigned long long) utmp2); + } + + printf("\n"); + /* do nothing, necessary ops done */ + } else if (type == LOP_SPECIAL) { + /* This op code is a special op in the object, no matter + that it might fall into the standard op range in this + compile Thatis, these are special opcodes between + special_opcode_base and MAX_LINE_OP_CODE. (including + special_opcode_base and MAX_LINE_OP_CODE) */ + char special[50]; + unsigned origop = opcode; + + opcode = opcode - prefix.pf_opcode_base; + address = address + prefix.pf_minimum_instruction_length * + (opcode / prefix.pf_line_range); + line = + line + prefix.pf_line_base + + opcode % prefix.pf_line_range; + + sprintf(special, "Specialop %3u", origop); + print_line_detail(special, + opcode, address, (int) file, line, column, + is_stmt, basic_block, end_sequence, + prologue_end, epilogue_begin, isa); + + basic_block = false; + + } else if (type == LOP_STANDARD) { + switch (opcode) { + + case DW_LNS_copy:{ + + print_line_detail("DW_LNS_copy", + opcode, address, file, line, + column, is_stmt, basic_block, + end_sequence, prologue_end, + epilogue_begin, isa); + + basic_block = false; + break; + } + + case DW_LNS_advance_pc:{ + Dwarf_Unsigned utmp2; + + + DECODE_LEB128_UWORD(line_ptr, utmp2); + printf("DW_LNS_advance_pc val %lld 0x%llx\n", + (long long) (Dwarf_Word) utmp2, + (long long) (Dwarf_Word) utmp2); + leb128_num = (Dwarf_Word) utmp2; + address = + address + + prefix.pf_minimum_instruction_length * + leb128_num; + break; + } + + case DW_LNS_advance_line:{ + Dwarf_Signed stmp; + + + DECODE_LEB128_SWORD(line_ptr, stmp); + advance_line = (Dwarf_Sword) stmp; + printf("DW_LNS_advance_line val %lld 0x%llx\n", + (long long) advance_line, + (long long) advance_line); + line = line + advance_line; + break; + } + + case DW_LNS_set_file:{ + Dwarf_Unsigned utmp2; + + + DECODE_LEB128_UWORD(line_ptr, utmp2); + file = (Dwarf_Word) utmp2; + printf("DW_LNS_set_file %ld\n", (long) file); + break; + } + + case DW_LNS_set_column:{ + Dwarf_Unsigned utmp2; + + + DECODE_LEB128_UWORD(line_ptr, utmp2); + column = (Dwarf_Word) utmp2; + printf("DW_LNS_set_column val %lld 0x%llx\n", + (long long) column, (long long) column); + break; + } + + case DW_LNS_negate_stmt:{ + is_stmt = !is_stmt; + printf("DW_LNS_negate_stmt\n"); + break; + } + + case DW_LNS_set_basic_block:{ + + printf("DW_LNS_set_basic_block\n"); + basic_block = true; + break; + } + + case DW_LNS_const_add_pc:{ + opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base; + address = + address + + prefix.pf_minimum_instruction_length * (opcode / + prefix. + pf_line_range); + + printf("DW_LNS_const_add_pc new address 0x%llx\n", + (long long) address); + break; + } + + case DW_LNS_fixed_advance_pc:{ + + READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half, + line_ptr, sizeof(Dwarf_Half)); + line_ptr += sizeof(Dwarf_Half); + address = address + fixed_advance_pc; + printf("DW_LNS_fixed_advance_pc val %lld 0x%llx" + " new address 0x%llx\n", + (long long) fixed_advance_pc, + (long long) fixed_advance_pc, + (long long) address); + break; + } + case DW_LNS_set_prologue_end:{ + + prologue_end = true; + printf("DW_LNS_set_prologue_end set true.\n"); + break; + + + } + /* New in DWARF3 */ + case DW_LNS_set_epilogue_begin:{ + epilogue_begin = true; + printf("DW_LNS_set_epilogue_begin set true.\n"); + break; + } + + /* New in DWARF3 */ + case DW_LNS_set_isa:{ + Dwarf_Unsigned utmp2; + + DECODE_LEB128_UWORD(line_ptr, utmp2); + isa = utmp2; + printf("DW_LNS_set_isa new value 0x%llx.\n", + (unsigned long long) utmp2); + if (isa != utmp2) { + /* The value of the isa did not fit in our + local so we record it wrong. declare an + error. */ + dwarf_free_line_table_prefix(&prefix); + + _dwarf_error(dbg, error, + DW_DLE_LINE_NUM_OPERANDS_BAD); + return (DW_DLV_ERROR); + } + break; + } + } + + + } else if (type == LOP_EXTENDED) { + Dwarf_Unsigned utmp3 = 0; + Dwarf_Word instr_length = 0; + Dwarf_Small ext_opcode = 0; + + DECODE_LEB128_UWORD(line_ptr, utmp3); + instr_length = (Dwarf_Word) utmp3; + ext_opcode = *(Dwarf_Small *) line_ptr; + line_ptr++; + switch (ext_opcode) { + + case DW_LNE_end_sequence:{ + end_sequence = true; + + print_line_detail("DW_LNE_end_sequence extended", + opcode, address, file, line, + column, is_stmt, basic_block, + end_sequence, prologue_end, + epilogue_begin, isa); + + address = 0; + file = 1; + line = 1; + column = 0; + is_stmt = prefix.pf_default_is_stmt; + basic_block = false; + end_sequence = false; + prologue_end = false; + epilogue_begin = false; + + + break; + } + + case DW_LNE_set_address:{ + if (instr_length - 1 == dbg->de_pointer_size) { + READ_UNALIGNED(dbg, address, Dwarf_Addr, + line_ptr, dbg->de_pointer_size); + + line_ptr += dbg->de_pointer_size; + printf("DW_LNE_set_address address 0x%llx\n", + (long long) address); + } else { + dwarf_free_line_table_prefix(&prefix); + _dwarf_error(dbg, error, + DW_DLE_LINE_SET_ADDR_ERROR); + return (DW_DLV_ERROR); + } + + break; + } + + case DW_LNE_define_file:{ + + + Dwarf_Small *fn; + Dwarf_Unsigned di; + Dwarf_Unsigned tlm; + Dwarf_Unsigned fl; + + fn = (Dwarf_Small *) line_ptr; + line_ptr = line_ptr + strlen((char *) line_ptr) + 1; + + di = _dwarf_decode_u_leb128(line_ptr, + &leb128_length); + line_ptr = line_ptr + leb128_length; + + tlm = _dwarf_decode_u_leb128(line_ptr, + &leb128_length); + line_ptr = line_ptr + leb128_length; + + fl = _dwarf_decode_u_leb128(line_ptr, + &leb128_length); + line_ptr = line_ptr + leb128_length; + + + printf("DW_LNE_define_file %s \n", fn); + printf(" dir index %d\n", (int) di); + { + time_t tt3 = (time_t) tlm; + + /* ctime supplies newline */ + printf(" last time 0x%x %s", + (unsigned) tlm, ctime(&tt3)); + } + printf(" file length %ld 0x%lx\n", + (long) fl, (unsigned long) fl); + + break; + } + + default:{ + dwarf_free_line_table_prefix(&prefix); + _dwarf_error(dbg, error, + DW_DLE_LINE_EXT_OPCODE_BAD); + return (DW_DLV_ERROR); + } + } + + } + } + + dwarf_free_line_table_prefix(&prefix); + return (DW_DLV_OK); +} + +/* + This is support for dwarfdump: making it possible + for clients wanting line detail info on stdout + to get that detail without including internal libdwarf + header information. + Caller passes in compilation unit DIE. + The _dwarf version is obsolete (though supported for + compatibility. + The dwarf_ version is preferred. +*/ +int +dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error) +{ + int res; + + res = _dwarf_internal_printlines(die, error); + if (res != DW_DLV_OK) { + return res; + } + return res; +} +int +_dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error) +{ + int res; + + res = _dwarf_internal_printlines(die, error); + if (res != DW_DLV_OK) { + return res; + } + return res; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_pubtypes.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_pubtypes.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,148 @@ +/* + + Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + +/* Reads DWARF3 .debug_pubtypes section. */ + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_types.h" +#include "dwarf_global.h" + +int +dwarf_get_pubtypes(Dwarf_Debug dbg, + Dwarf_Type ** types, + Dwarf_Signed * ret_type_count, Dwarf_Error * error) +{ + int res; + + res = + _dwarf_load_section(dbg, + dbg->de_debug_pubtypes_index, + &dbg->de_debug_pubtypes, error); + if (res != DW_DLV_OK) { + return res; + } + + return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_pubtypes, dbg->de_debug_pubtypes_size, (Dwarf_Global **) types, /* type + punning, + Dwarf_Type + is never + a + completed + type */ + ret_type_count, error, DW_DLA_PUBTYPES_CONTEXT, DW_DLA_GLOBAL, /* We + don't + have + DW_DLA_PUBTYPES, + so use + DW_DLA_GLOBAL. */ + DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD, + DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR); +} + +/* Deallocating fully requires deallocating the list + and all entries. But some internal data is + not exposed, so we need a function with internal knowledge. +*/ + +void +dwarf_pubtypes_dealloc(Dwarf_Debug dbg, Dwarf_Type * dwgl, + Dwarf_Signed count) +{ + _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl, count, DW_DLA_PUBTYPES_CONTEXT, DW_DLA_GLOBAL, /* We + don't + have + DW_DLA_PUBTYPES, + so use + DW_DLA_GLOBAL. */ + DW_DLA_LIST); + return; +} + + + +int +dwarf_pubtypename(Dwarf_Type type_in, char **ret_name, + Dwarf_Error * error) +{ + Dwarf_Global type = (Dwarf_Global) type_in; + + if (type == NULL) { + _dwarf_error(NULL, error, DW_DLE_TYPE_NULL); + return (DW_DLV_ERROR); + } + + *ret_name = (char *) (type->gl_name); + return DW_DLV_OK; +} + + +int +dwarf_pubtype_type_die_offset(Dwarf_Type type_in, + Dwarf_Off * ret_offset, + Dwarf_Error * error) +{ + Dwarf_Global type = (Dwarf_Global) type_in; + + return dwarf_global_die_offset(type, ret_offset, error); +} + + +int +dwarf_pubtype_cu_offset(Dwarf_Type type_in, + Dwarf_Off * ret_offset, Dwarf_Error * error) +{ + Dwarf_Global type = (Dwarf_Global) type_in; + + return dwarf_global_cu_offset(type, ret_offset, error); + +} + + +int +dwarf_pubtype_name_offsets(Dwarf_Type type_in, + char **returned_name, + Dwarf_Off * die_offset, + Dwarf_Off * cu_die_offset, + Dwarf_Error * error) +{ + Dwarf_Global type = (Dwarf_Global) type_in; + + return dwarf_global_name_offsets(type, + returned_name, + die_offset, cu_die_offset, error); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_query.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_query.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,619 @@ +/* + + Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_die_deliv.h" + +int +dwarf_get_address_size(Dwarf_Debug dbg, + Dwarf_Half * ret_addr_size, Dwarf_Error * error) +{ + Dwarf_Half address_size; + + if (dbg == 0) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + /* length size same as address size */ + address_size = dbg->de_pointer_size; + *ret_addr_size = address_size; + return DW_DLV_OK; +} + +int +dwarf_dieoffset(Dwarf_Die die, + Dwarf_Off * ret_offset, Dwarf_Error * error) +{ + CHECK_DIE(die, DW_DLV_ERROR); + + *ret_offset = (die->di_debug_info_ptr - + die->di_cu_context->cc_dbg->de_debug_info); + return DW_DLV_OK; +} + + +/* + This function returns the offset of + the die relative to the start of its + compilation-unit rather than .debug_info. + Returns DW_DLV_ERROR on error. +*/ +int +dwarf_die_CU_offset(Dwarf_Die die, + Dwarf_Off * cu_off, Dwarf_Error * error) +{ + Dwarf_CU_Context cu_context; + + CHECK_DIE(die, DW_DLV_ERROR); + cu_context = die->di_cu_context; + + *cu_off = + (die->di_debug_info_ptr - cu_context->cc_dbg->de_debug_info - + cu_context->cc_debug_info_offset); + return DW_DLV_OK; +} + + +int +dwarf_tag(Dwarf_Die die, Dwarf_Half * tag, Dwarf_Error * error) +{ + CHECK_DIE(die, DW_DLV_ERROR); + + + *tag = (die->di_abbrev_list->ab_tag); + return DW_DLV_OK; +} + + +int +dwarf_attrlist(Dwarf_Die die, + Dwarf_Attribute ** attrbuf, + Dwarf_Signed * attrcnt, Dwarf_Error * error) +{ + Dwarf_Word attr_count = 0; + Dwarf_Word i = 0; + Dwarf_Half attr = 0; + Dwarf_Half attr_form = 0; + Dwarf_Byte_Ptr abbrev_ptr = 0; + Dwarf_Abbrev_List abbrev_list = 0; + Dwarf_Attribute new_attr = 0; + Dwarf_Attribute head_attr = NULL; + Dwarf_Attribute curr_attr = NULL; + Dwarf_Attribute *attr_ptr = 0; + Dwarf_Debug dbg = 0; + Dwarf_Byte_Ptr info_ptr = 0; + + CHECK_DIE(die, DW_DLV_ERROR); + dbg = die->di_cu_context->cc_dbg; + + abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context, + die->di_abbrev_list-> + ab_code); + if (abbrev_list == NULL) { + _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_BAD); + return (DW_DLV_ERROR); + } + abbrev_ptr = abbrev_list->ab_abbrev_ptr; + + info_ptr = die->di_debug_info_ptr; + SKIP_LEB128_WORD(info_ptr); + + do { + Dwarf_Unsigned utmp2; + + DECODE_LEB128_UWORD(abbrev_ptr, utmp2); + attr = (Dwarf_Half) utmp2; + DECODE_LEB128_UWORD(abbrev_ptr, utmp2); + attr_form = (Dwarf_Half) utmp2; + + if (attr != 0) { + new_attr = + (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1); + if (new_attr == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + new_attr->ar_attribute = attr; + new_attr->ar_attribute_form_direct = attr_form; + new_attr->ar_attribute_form = attr_form; + if (attr_form == DW_FORM_indirect) { + Dwarf_Unsigned utmp6; + + /* DECODE_LEB128_UWORD does info_ptr update */ + DECODE_LEB128_UWORD(info_ptr, utmp6); + attr_form = (Dwarf_Half) utmp6; + new_attr->ar_attribute_form = attr_form; + } + new_attr->ar_cu_context = die->di_cu_context; + new_attr->ar_debug_info_ptr = info_ptr; + + info_ptr += _dwarf_get_size_of_val(dbg, attr_form, info_ptr, + die->di_cu_context-> + cc_length_size); + + if (head_attr == NULL) + head_attr = curr_attr = new_attr; + else { + curr_attr->ar_next = new_attr; + curr_attr = new_attr; + } + attr_count++; + } + } while (attr != 0 || attr_form != 0); + + if (attr_count == 0) { + *attrbuf = NULL; + *attrcnt = 0; + return (DW_DLV_NO_ENTRY); + } + + attr_ptr = (Dwarf_Attribute *) + _dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count); + if (attr_ptr == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + curr_attr = head_attr; + for (i = 0; i < attr_count; i++) { + *(attr_ptr + i) = curr_attr; + curr_attr = curr_attr->ar_next; + } + + *attrbuf = attr_ptr; + *attrcnt = attr_count; + return (DW_DLV_OK); +} + + +/* + This function takes a die, and an attr, and returns + a pointer to the start of the value of that attr in + the given die in the .debug_info section. The form + is returned in *attr_form. + + Returns NULL on error, or if attr is not found. + However, *attr_form is 0 on error, and positive + otherwise. +*/ +static Dwarf_Byte_Ptr +_dwarf_get_value_ptr(Dwarf_Die die, + Dwarf_Half attr, Dwarf_Half * attr_form) +{ + Dwarf_Byte_Ptr abbrev_ptr; + Dwarf_Abbrev_List abbrev_list; + Dwarf_Half curr_attr; + Dwarf_Half curr_attr_form; + Dwarf_Byte_Ptr info_ptr; + + abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context, + die->di_abbrev_list-> + ab_code); + if (abbrev_list == NULL) { + *attr_form = 0; + return (NULL); + } + abbrev_ptr = abbrev_list->ab_abbrev_ptr; + + info_ptr = die->di_debug_info_ptr; + SKIP_LEB128_WORD(info_ptr); + + do { + Dwarf_Unsigned utmp3; + + DECODE_LEB128_UWORD(abbrev_ptr, utmp3); + curr_attr = (Dwarf_Half) utmp3; + DECODE_LEB128_UWORD(abbrev_ptr, utmp3); + curr_attr_form = (Dwarf_Half) utmp3; + if (curr_attr_form == DW_FORM_indirect) { + Dwarf_Unsigned utmp6; + + /* DECODE_LEB128_UWORD updates info_ptr */ + DECODE_LEB128_UWORD(info_ptr, utmp6); + curr_attr_form = (Dwarf_Half) utmp6; + } + + if (curr_attr == attr) { + *attr_form = curr_attr_form; + return (info_ptr); + } + + info_ptr += _dwarf_get_size_of_val(die->di_cu_context->cc_dbg, + curr_attr_form, info_ptr, + die->di_cu_context-> + cc_length_size); + } while (curr_attr != 0 || curr_attr_form != 0); + + *attr_form = 1; + return (NULL); +} + + +int +dwarf_diename(Dwarf_Die die, char **ret_name, Dwarf_Error * error) +{ + Dwarf_Half attr_form; + Dwarf_Debug dbg; + Dwarf_Byte_Ptr info_ptr; + Dwarf_Unsigned string_offset; + int res; + + CHECK_DIE(die, DW_DLV_ERROR); + + info_ptr = _dwarf_get_value_ptr(die, DW_AT_name, &attr_form); + if (info_ptr == NULL) { + if (attr_form == 0) { + _dwarf_error(die->di_cu_context->cc_dbg, error, + DW_DLE_DIE_BAD); + return (DW_DLV_ERROR); + } + return DW_DLV_NO_ENTRY; + } + + if (attr_form == DW_FORM_string) { + *ret_name = (char *) (info_ptr); + return DW_DLV_OK; + } + + dbg = die->di_cu_context->cc_dbg; + if (attr_form != DW_FORM_strp) { + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + + READ_UNALIGNED(dbg, string_offset, Dwarf_Unsigned, + info_ptr, die->di_cu_context->cc_length_size); + + if (string_offset >= dbg->de_debug_str_size) { + _dwarf_error(dbg, error, DW_DLE_STRING_OFFSET_BAD); + return (DW_DLV_ERROR); + } + + res = + _dwarf_load_section(dbg, + dbg->de_debug_str_index, + &dbg->de_debug_str, error); + if (res != DW_DLV_OK) { + return res; + } + + *ret_name = (char *) (dbg->de_debug_str + string_offset); + return DW_DLV_OK; +} + + +int +dwarf_hasattr(Dwarf_Die die, + Dwarf_Half attr, + Dwarf_Bool * return_bool, Dwarf_Error * error) +{ + Dwarf_Half attr_form; + + CHECK_DIE(die, DW_DLV_ERROR); + + if (_dwarf_get_value_ptr(die, attr, &attr_form) == NULL) { + if (attr_form == 0) { + _dwarf_error(die->di_cu_context->cc_dbg, error, + DW_DLE_DIE_BAD); + return (DW_DLV_ERROR); + } + *return_bool = false; + return DW_DLV_OK; + } + + *return_bool = (true); + return DW_DLV_OK; +} + + +int +dwarf_attr(Dwarf_Die die, + Dwarf_Half attr, + Dwarf_Attribute * ret_attr, Dwarf_Error * error) +{ + Dwarf_Half attr_form; + Dwarf_Attribute attrib; + Dwarf_Byte_Ptr info_ptr; + Dwarf_Debug dbg; + + CHECK_DIE(die, DW_DLV_ERROR); + dbg = die->di_cu_context->cc_dbg; + + info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form); + if (info_ptr == NULL) { + if (attr_form == 0) { + _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + return (DW_DLV_ERROR); + } + return DW_DLV_NO_ENTRY; + } + + attrib = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1); + if (attrib == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + attrib->ar_attribute = attr; + attrib->ar_attribute_form = attr_form; + attrib->ar_attribute_form_direct = attr_form; + attrib->ar_cu_context = die->di_cu_context; + attrib->ar_debug_info_ptr = info_ptr; + *ret_attr = (attrib); + return DW_DLV_OK; +} + + +int +dwarf_lowpc(Dwarf_Die die, + Dwarf_Addr * return_addr, Dwarf_Error * error) +{ + Dwarf_Addr ret_addr = 0; + Dwarf_Byte_Ptr info_ptr = 0; + Dwarf_Half attr_form = 0; + Dwarf_Debug dbg = 0; + + CHECK_DIE(die, DW_DLV_ERROR); + + dbg = die->di_cu_context->cc_dbg; + info_ptr = _dwarf_get_value_ptr(die, DW_AT_low_pc, &attr_form); + if ((info_ptr == NULL && attr_form == 0) || + (info_ptr != NULL && attr_form != DW_FORM_addr)) { + _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + return (DW_DLV_ERROR); + } + if (info_ptr == NULL) { + return (DW_DLV_NO_ENTRY); + } + + + READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr, + info_ptr, dbg->de_pointer_size); + + *return_addr = ret_addr; + return (DW_DLV_OK); +} + + +int +dwarf_highpc(Dwarf_Die die, + Dwarf_Addr * return_addr, Dwarf_Error * error) +{ + Dwarf_Addr ret_addr; + Dwarf_Byte_Ptr info_ptr; + Dwarf_Half attr_form; + Dwarf_Debug dbg; + + CHECK_DIE(die, DW_DLV_ERROR); + + dbg = die->di_cu_context->cc_dbg; + info_ptr = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form); + if ((info_ptr == NULL && attr_form == 0) || + (info_ptr != NULL && attr_form != DW_FORM_addr)) { + _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + return (DW_DLV_ERROR); + } + if (info_ptr == NULL) { + return (DW_DLV_NO_ENTRY); + } + + READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr, + info_ptr, dbg->de_pointer_size); + + *return_addr = ret_addr; + return (DW_DLV_OK); +} + + +/* + Takes a die, an attribute attr, and checks if attr + occurs in die. Attr is required to be an attribute + whose form is in the "constant" class. If attr occurs + in die, the value is returned. + Returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY as + appropriate. Sets the value thru the pointer return_val. + This function is meant to do all the + processing for dwarf_bytesize, dwarf_bitsize, dwarf_bitoffset, + and dwarf_srclang. +*/ +static int +_dwarf_die_attr_unsigned_constant(Dwarf_Die die, + Dwarf_Half attr, + Dwarf_Unsigned * return_val, + Dwarf_Error * error) +{ + Dwarf_Byte_Ptr info_ptr; + Dwarf_Half attr_form; + Dwarf_Unsigned ret_value; + Dwarf_Debug dbg; + + CHECK_DIE(die, DW_DLV_ERROR); + + dbg = die->di_cu_context->cc_dbg; + info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form); + if (info_ptr != NULL) { + switch (attr_form) { + + case DW_FORM_data1: + *return_val = (*(Dwarf_Small *) info_ptr); + return (DW_DLV_OK); + + case DW_FORM_data2: + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + info_ptr, sizeof(Dwarf_Shalf)); + *return_val = ret_value; + return (DW_DLV_OK); + + case DW_FORM_data4: + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + info_ptr, sizeof(Dwarf_sfixed)); + *return_val = ret_value; + return (DW_DLV_OK); + + case DW_FORM_data8: + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + info_ptr, sizeof(Dwarf_Unsigned)); + *return_val = ret_value; + return (DW_DLV_OK); + + case DW_FORM_udata: + *return_val = (_dwarf_decode_u_leb128(info_ptr, NULL)); + return (DW_DLV_OK); + + default: + _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + return (DW_DLV_ERROR); + } + } + if (attr_form == 0) { + _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + return (DW_DLV_ERROR); + } + return DW_DLV_NO_ENTRY; +} + + +int +dwarf_bytesize(Dwarf_Die die, + Dwarf_Unsigned * ret_size, Dwarf_Error * error) +{ + Dwarf_Unsigned luns; + int res = + _dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size, &luns, + error); + + *ret_size = luns; + return res; +} + + +int +dwarf_bitsize(Dwarf_Die die, + Dwarf_Unsigned * ret_size, Dwarf_Error * error) +{ + Dwarf_Unsigned luns; + int res; + + res = + _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size, &luns, + error); + *ret_size = luns; + return res; +} + + +int +dwarf_bitoffset(Dwarf_Die die, + Dwarf_Unsigned * ret_size, Dwarf_Error * error) +{ + Dwarf_Unsigned luns; + int res; + + res = + _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_offset, &luns, + error); + *ret_size = luns; + return res; +} + + +/* Refer section 3.1, page 21 in Dwarf Definition. */ +int +dwarf_srclang(Dwarf_Die die, + Dwarf_Unsigned * ret_size, Dwarf_Error * error) +{ + Dwarf_Unsigned luns; + int res; + + res = + _dwarf_die_attr_unsigned_constant(die, DW_AT_language, &luns, + error); + *ret_size = luns; + return res; +} + + +/* Refer section 5.4, page 37 in Dwarf Definition. */ +int +dwarf_arrayorder(Dwarf_Die die, + Dwarf_Unsigned * ret_size, Dwarf_Error * error) +{ + Dwarf_Unsigned luns; + int res; + + res = + _dwarf_die_attr_unsigned_constant(die, DW_AT_ordering, &luns, + error); + *ret_size = luns; + return res; +} + +/* + Return DW_DLV_OK if ok + DW_DLV_ERROR if failure. + + If the die and the attr are not related the result is + meaningless. +*/ +int +dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr, Dwarf_Off * offset, /* return + offset + thru + this + ptr + */ + Dwarf_Error * error) +{ + Dwarf_Off attroff; + + CHECK_DIE(die, DW_DLV_ERROR); + + attroff = (attr->ar_debug_info_ptr - + die->di_cu_context->cc_dbg->de_debug_info); + *offset = attroff; + return DW_DLV_OK; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_sort_line.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_sort_line.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,718 @@ +/* + Copyright (C) 2000,2002,2004,2006 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include +#include "dwarf_line.h" +#ifdef HAVE_ALLOCA_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif + +#define MINIMUM_POSSIBLE_PROLOG_LEN 10 /* 10 is based on */ + /* the definition of the DWARF2/3 line table prolog. The value + here should be >8 (accounting for a 64 bit read) and <= the + length of a legal DWARF2/3 line prolog, which is at least 10 + bytes long (but can be longer). What this constant helps + avoid is reading past the end of a malloc'd buffer in + _dwarf_update_line_sec(). */ + +static int + _dwarf_update_line_sec(Dwarf_Small * line_ptr, + unsigned long remaining_bytes, + int *any_change, + int length_size, + int *err_code, Dwarf_Small ** new_line_ptr); + +/* Used to construct + a linked list of so we can sort and reorder the line info. +*/ +struct a_line_area { + Dwarf_Addr ala_address; /* from DW_LNE_set_address */ + Dwarf_Unsigned ala_offset; /* byte offset in buffer */ + Dwarf_Unsigned ala_length; /* byte length in buffer */ + long ala_entry_num; /* to guarantee stable sort */ + struct a_line_area *ala_next; +}; + + +/* + Written to support the SGI IRIX static linker. + It helps SGI IRIX ld + rearrange lines in .debug_line in a .o created with a text + section per function. The SGI IRIX linker option is: + -OPT:procedure_reorder=ON + where ld-cord (cord(1)ing by ld, + not by cord(1)) may have changed the function order. + + Returns + DW_DLV_OK if nothing went wrong. + DW_DLV_ERROR if could not do anything due to + error. the original buffer is unchanged. + + is_64_bit must be passed in by caller and tells + if this is a 32 or 64bit pointer object section + being processed. + + err_code must be a non-null pointer to integer. + If DW_DLV_ERROR is returned that integer is set + to a dwarf error code so the caller may + print it for diagnostic purposes. + + *any_change is set here + set 0 if no sorting (movement) done. + set 1 if some sorting (movement) done. + on all returns. On error return sets to 0. + + The _dwarf name form is now obsolete, + the dwarf_ name for is preferred. + Both names supported. + +*/ +int +_dwarf_ld_sort_lines(void *orig_buffer, + unsigned long buffer_len, + int is_64_bit, int *any_change, int *err_code) +{ + return dwarf_ld_sort_lines(orig_buffer,buffer_len, + is_64_bit,any_change,err_code); +} +int +dwarf_ld_sort_lines(void *orig_buffer, + unsigned long buffer_len, + int is_64_bit, int *any_change, int *err_code) +{ + + int length_size = 4; + Dwarf_Small *orig_line_ptr; /* our local copy of the user's input + buffer */ + Dwarf_Small *line_ptr; /* starts at orig_line_ptr, gets + incremented thru to end of our copy + of the input buffer */ + Dwarf_Small *new_line_ptr; /* output of _dwarf_update_line_sec(), + used to update line_ptr as we pass + thru compilation units in a .o + .debug_line */ + + unsigned long remaining_bytes = buffer_len; /* total length of + original area left + to be processed. + Changes as we pass + thru compilation + units in a .o + .debug_line */ + + int sec_res; + int lany_change = 0; + int did_change = 0; + + if (is_64_bit) + length_size = 8; + + *any_change = 0; + line_ptr = malloc(buffer_len); + if (!line_ptr) { + *err_code = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + orig_line_ptr = line_ptr; + memcpy(line_ptr, orig_buffer, buffer_len); + + + /* + We must iterate thru each of a set of prologues and line data. + We process each set in turn. If all pass, we update the + passed-in buffer. */ + sec_res = DW_DLV_OK; + + for (sec_res = _dwarf_update_line_sec(line_ptr, + remaining_bytes, + &lany_change, + length_size, + err_code, + &new_line_ptr); + (sec_res == DW_DLV_OK) && (remaining_bytes > 0); + sec_res = _dwarf_update_line_sec(line_ptr, + remaining_bytes, + &lany_change, + length_size, + err_code, &new_line_ptr)) { + long bytes_used = new_line_ptr - line_ptr; + + line_ptr = new_line_ptr; + remaining_bytes -= bytes_used; + if (lany_change) { + did_change = 1; + } + if (remaining_bytes > 0) { + continue; + } + break; + } + if (sec_res == DW_DLV_ERROR) { + free(orig_line_ptr); + return sec_res; + } + + + /* all passed */ + if (did_change) { + /* So update the passed in buffer orig_buffer is caller's input + area. orig_line_ptr is our modified copy of input area. */ + memcpy(orig_buffer, orig_line_ptr, buffer_len); + *any_change = 1; + } + free(orig_line_ptr); + + return sec_res; +} + + +/* By setting ala_entry_num we guarantee a stable sort, + no duplicates + Sorting in address order. +*/ +static int +cmpr(const void *lin, const void *rin) +{ + const struct a_line_area *l = lin; + const struct a_line_area *r = rin; + + if (l->ala_address < r->ala_address) { + return -1; + } + if (l->ala_address > r->ala_address) { + return 1; + } + if (l->ala_entry_num < r->ala_entry_num) { + return -1; + } + if (l->ala_entry_num > r->ala_entry_num) { + return 1; + } + return 0; /* should never happen. */ +} + + +/* + On entry: + line_ptr must point to first + byte of a line group for one (original) .o + + remaining_bytes is the size of the area pointed to + by line_ptr: may be larger than the + current original compilation unit . + + length size is 4 for 32bit pointers, 8 for 64bit pointers + in the data pointed to. + + + On return: + return DW_DLV_OK if all ok. (ignore + *err_code in this case) + + return DW_DLV_ERROR and set *err_code if an error. + + If some line data was moved around, set *any_change to 1. + If error or no movement, set *any_change to 0; + + Set *new_line_ptr to one-byte-past the end of the + current original compilation unit (not necessary + if returning DW_DLV_ERROR, but not harmful). + + + This copies the entire array to a malloc area, then + mallocs pieces of it (another malloc) for sorting a CU entries + and copying back. Then at end the whole new thing copied in. + The result is that on error, the input is not touched. + + An alternative would be to just update a piece at a time + and on error stop updating but leave what was done, done. + This alternative would save some temporary malloc space. + + +*/ +static int +_dwarf_update_line_sec(Dwarf_Small * line_ptr, + unsigned long remaining_bytes, + int *any_change, + int length_size, + int *err_code, Dwarf_Small ** new_line_ptr) +{ + + + /* + This points to the last byte of the .debug_line portion for the + current cu. */ + Dwarf_Small *line_ptr_end = 0; + + /* + This points to the end of the statement program prologue for the + current cu, and serves to check that the prologue was correctly + decoded. */ + + Dwarf_Small *orig_line_ptr = 0; + + /* These are the fields of the statement program header. */ + struct Dwarf_Debug_s dbg_data; + Dwarf_Debug dbg = &dbg_data; + + /* These are the state machine state variables. */ + Dwarf_Addr address = 0; + Dwarf_Word line = 1; + Dwarf_Bool is_stmt = false; + + /* Dwarf_Bool prologue_end; Dwarf_Bool epilogue_begin; */ + Dwarf_Small isa = 0; + + + struct a_line_area *area_base = 0; + struct a_line_area *area_current = 0; + long area_count = 0; + + Dwarf_Addr last_address = 0; + int need_to_sort = 0; + + /* + This is the current opcode read from the statement program. */ + Dwarf_Small opcode = 0; + + + /* + These variables are used to decode leb128 numbers. Leb128_num + holds the decoded number, and leb128_length is its length in + bytes. */ + Dwarf_Word leb128_num = 0; + Dwarf_Sword advance_line = 0; + + /* + This is the operand of the latest fixed_advance_pc extended + opcode. */ + Dwarf_Half fixed_advance_pc = 0; + + /* This is the length of an extended opcode instr. */ + Dwarf_Word instr_length = 0; + Dwarf_Small ext_opcode = 0; + struct Line_Table_Prefix_s prefix; + + + + memset(dbg, 0, sizeof(struct Dwarf_Debug_s)); + dbg->de_copy_word = memcpy; + /* + Following is a straightforward decoding of the statement program + prologue information. */ + *any_change = 0; + + + orig_line_ptr = line_ptr; + if (remaining_bytes < MINIMUM_POSSIBLE_PROLOG_LEN) { + /* We are at the end. Remaining should be zero bytes, padding. + This is really just 'end of CU buffer' not an error. The is + no 'entry' left so report there is none. We don't want to + READ_UNALIGNED the total_length below and then belatedly + discover that we read off the end already. */ + return (DW_DLV_NO_ENTRY); + } + + dwarf_init_line_table_prefix(&prefix); + { + Dwarf_Small *line_ptr_out = 0; + Dwarf_Error error; + int dres = dwarf_read_line_table_prefix(dbg, + line_ptr, + remaining_bytes, + &line_ptr_out, + &prefix, &error); + + if (dres == DW_DLV_ERROR) { + dwarf_free_line_table_prefix(&prefix); + *err_code = dwarf_errno(error); + dwarf_dealloc(dbg, error, DW_DLA_ERROR); + return dres; + } + if (dres == DW_DLV_NO_ENTRY) { + dwarf_free_line_table_prefix(&prefix); + return dres; + } + line_ptr_end = prefix.pf_line_ptr_end; + + line_ptr = line_ptr_out; + } + + + /* Initialize the state machine. */ + /* file = 1; */ + /* column = 0; */ + is_stmt = prefix.pf_default_is_stmt; + /* basic_block = false; */ + /* end_sequence = false; */ + /* prologue_end = false; */ + /* epilogue_begin = false; */ + isa = 0; + + + /* Start of statement program. */ + while (line_ptr < line_ptr_end) { + int type; + + Dwarf_Small *stmt_prog_entry_start = line_ptr; + + opcode = *(Dwarf_Small *) line_ptr; + line_ptr++; + /* 'type' is the output */ + WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base, + prefix.pf_opcode_length_table, line_ptr, + prefix.pf_std_op_count); + + if (type == LOP_DISCARD) { + int oc; + int opcnt = prefix.pf_opcode_length_table[opcode]; + + for (oc = 0; oc < opcnt; oc++) { + /* + ** Read and discard operands we don't + ** understand. + ** arbitrary choice of unsigned read. + ** signed read would work as well. + */ + Dwarf_Unsigned utmp2; + + DECODE_LEB128_UWORD(line_ptr, utmp2); + } + + } else if (type == LOP_SPECIAL) { + opcode = opcode - prefix.pf_opcode_base; + address = address + prefix.pf_minimum_instruction_length * + (opcode / prefix.pf_line_range); + line = + line + prefix.pf_line_base + + opcode % prefix.pf_line_range; + + /* basic_block = false; */ + + + } else if (type == LOP_STANDARD) { + + + switch (opcode) { + + + case DW_LNS_copy:{ + + /* basic_block = false; */ + break; + } + + case DW_LNS_advance_pc:{ + Dwarf_Unsigned utmp2; + + + DECODE_LEB128_UWORD(line_ptr, utmp2); + leb128_num = (Dwarf_Word) utmp2; + address = + address + + prefix.pf_minimum_instruction_length * + leb128_num; + break; + } + + case DW_LNS_advance_line:{ + Dwarf_Signed stmp; + + + DECODE_LEB128_SWORD(line_ptr, stmp); + advance_line = (Dwarf_Sword) stmp; + line = line + advance_line; + break; + } + + case DW_LNS_set_file:{ + Dwarf_Unsigned utmp2; + + + DECODE_LEB128_UWORD(line_ptr, utmp2); + /* file = (Dwarf_Word)utmp2; */ + break; + } + + case DW_LNS_set_column:{ + Dwarf_Unsigned utmp2; + + + DECODE_LEB128_UWORD(line_ptr, utmp2); + /* column = (Dwarf_Word)utmp2; */ + break; + } + + case DW_LNS_negate_stmt:{ + + is_stmt = !is_stmt; + break; + } + + case DW_LNS_set_basic_block:{ + + /* basic_block = true; */ + break; + } + + case DW_LNS_const_add_pc:{ + opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base; + address = + address + + prefix.pf_minimum_instruction_length * (opcode / + prefix. + pf_line_range); + + break; + } + + case DW_LNS_fixed_advance_pc:{ + + READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half, + line_ptr, sizeof(Dwarf_Half)); + line_ptr += sizeof(Dwarf_Half); + address = address + fixed_advance_pc; + break; + } + /* New in DWARF3 */ + case DW_LNS_set_prologue_end:{ + + /* prologue_end = true; */ + break; + + + } + /* New in DWARF3 */ + case DW_LNS_set_epilogue_begin:{ + /* epilogue_begin = true; */ + break; + } + + /* New in DWARF3 */ + case DW_LNS_set_isa:{ + Dwarf_Unsigned utmp2; + + DECODE_LEB128_UWORD(line_ptr, utmp2); + isa = utmp2; + if (isa != utmp2) { + /* The value of the isa did not fit in our + local so we record it wrong. declare an + error. */ + dwarf_free_line_table_prefix(&prefix); + + *err_code = DW_DLE_LINE_NUM_OPERANDS_BAD; + return (DW_DLV_ERROR); + } + break; + } + + } + } else if (type == LOP_EXTENDED) { + + + Dwarf_Unsigned utmp3; + + DECODE_LEB128_UWORD(line_ptr, utmp3); + instr_length = (Dwarf_Word) utmp3; + ext_opcode = *(Dwarf_Small *) line_ptr; + line_ptr++; + switch (ext_opcode) { + + case DW_LNE_end_sequence:{ + /* end_sequence = true; */ + + address = 0; + /* file = 1; */ + line = 1; + /* column = 0; */ + is_stmt = prefix.pf_default_is_stmt; + /* basic_block = false; */ + /* end_sequence = false; */ + /* prologue_end = false; */ + /* epilogue_begin = false; */ + + + break; + } + + case DW_LNE_set_address:{ + if (instr_length - 1 == length_size) { + struct a_line_area *area; + + READ_UNALIGNED(dbg, address, Dwarf_Addr, + line_ptr, length_size); + /* Here we need to remember the offset into the + buffer and check to see if address went + down. */ + if (address < last_address) { + need_to_sort = 1; + } + last_address = address; + + area = alloca(sizeof(struct a_line_area)); + area->ala_address = address; + area->ala_offset = stmt_prog_entry_start - + orig_line_ptr; + area->ala_entry_num = area_count; + area->ala_next = 0; + area->ala_length = 0; + if (area_current) { + area_current->ala_next = area; + area_current->ala_length = + area->ala_offset - + area_current->ala_offset; + } + ++area_count; + area_current = area; + if (area_base == 0) { + area_base = area; + } + + line_ptr += length_size; + } else { + *err_code = DW_DLE_LINE_SET_ADDR_ERROR; + dwarf_free_line_table_prefix(&prefix); + return (DW_DLV_ERROR); + } + + + break; + } + + case DW_LNE_define_file:{ + + break; + } + + default:{ + *err_code = DW_DLE_LINE_EXT_OPCODE_BAD; + dwarf_free_line_table_prefix(&prefix); + return (DW_DLV_ERROR); + } + } + + } + } + + + *new_line_ptr = line_ptr; + if (!need_to_sort) { + dwarf_free_line_table_prefix(&prefix); + return (DW_DLV_OK); + } + + /* so now we have something to sort. First, finish off the last + area record: */ + area_current->ala_length = (line_ptr - orig_line_ptr) /* final + offset + */ + -area_current->ala_offset; + + /* Build and sort a simple array of sections. Forcing a stable sort + by comparing on sequence number. We will use the sorted list to + move sections of this part of the line table. Each 'section' + starting with a DW_LNE_set_address opcode, on the assumption + that such only get out of order where there was an ld-cord + function rearrangement and that it is meaningful to restart the + line info there. */ + { + struct a_line_area *ala_array; + struct a_line_area *local; + long start_len; + Dwarf_Small *new_area; + long i; + + ala_array = malloc(area_count * sizeof(struct a_line_area)); + if (!ala_array) { + dwarf_free_line_table_prefix(&prefix); + *err_code = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + + for (local = area_base, i = 0; local; + local = local->ala_next, ++i) { + + ala_array[i] = *local; + } + + qsort(ala_array, area_count, sizeof(struct a_line_area), cmpr); + + /* Now we must rearrange the pieces of the line table. */ + + start_len = + (prefix.pf_line_prologue_start + + prefix.pf_prologue_length) - orig_line_ptr; + new_area = malloc(remaining_bytes); + if (!new_area) { + free(ala_array); + *err_code = DW_DLE_ALLOC_FAIL; + dwarf_free_line_table_prefix(&prefix); + return DW_DLV_ERROR; + } + memcpy(new_area, orig_line_ptr, start_len); + line_ptr = new_area + start_len; + for (i = 0; i < area_count; ++i) { + memcpy(line_ptr, orig_line_ptr + + ala_array[i].ala_offset, ala_array[i].ala_length); + line_ptr += ala_array[i].ala_length; + } + + memcpy(orig_line_ptr, new_area, remaining_bytes); + + free(new_area); + free(ala_array); + ala_array = 0; + new_area = 0; + } + + *any_change = 1; + dwarf_free_line_table_prefix(&prefix); + return (DW_DLV_OK); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_string.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_string.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,81 @@ +/* + + Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" + +int +dwarf_get_str(Dwarf_Debug dbg, + Dwarf_Off offset, + char **string, + Dwarf_Signed * returned_str_len, Dwarf_Error * error) +{ + int res; + + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + + if (offset == dbg->de_debug_str_size) { + /* Normal (if we've iterated thru the set of strings using + dwarf_get_str and are at the end). */ + return DW_DLV_NO_ENTRY; + } + if (offset > dbg->de_debug_str_size) { + _dwarf_error(dbg, error, DW_DLE_DEBUG_STR_OFFSET_BAD); + return (DW_DLV_ERROR); + } + + if (string == NULL) { + _dwarf_error(dbg, error, DW_DLE_STRING_PTR_NULL); + return (DW_DLV_ERROR); + } + + res = + _dwarf_load_section(dbg, + dbg->de_debug_str_index, + &dbg->de_debug_str, error); + if (res != DW_DLV_OK) { + return res; + } + + *string = (char *) dbg->de_debug_str + offset; + + *returned_str_len = (strlen(*string)); + return DW_DLV_OK; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_stubs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_stubs.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,50 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include + + + + /*ARGSUSED*/ int +dwarf_nextglob(Dwarf_Debug dbg, + Dwarf_Global glob, + Dwarf_Global * returned_nextglob, Dwarf_Error * error) +{ + return (DW_DLV_NO_ENTRY); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_types.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_types.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,141 @@ +/* + + Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_types.h" +#include "dwarf_global.h" + +int +dwarf_get_types(Dwarf_Debug dbg, + Dwarf_Type ** types, + Dwarf_Signed * ret_type_count, Dwarf_Error * error) +{ + int res; + + res = + _dwarf_load_section(dbg, + dbg->de_debug_typenames_index, + &dbg->de_debug_typenames, error); + if (res != DW_DLV_OK) { + return res; + } + + return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_typenames, dbg->de_debug_typenames_size, (Dwarf_Global **) types, /* type + punning, + Dwarf_Type + is + never + a + completed + type + */ + ret_type_count, + error, + DW_DLA_TYPENAME_CONTEXT, + DW_DLA_TYPENAME, + DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD, + DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR); + +} + +/* Deallocating fully requires deallocating the list + and all entries. But some internal data is + not exposed, so we need a function with internal knowledge. +*/ + +void +dwarf_types_dealloc(Dwarf_Debug dbg, Dwarf_Type * dwgl, + Dwarf_Signed count) +{ + _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl, + count, + DW_DLA_TYPENAME_CONTEXT, + DW_DLA_TYPENAME, DW_DLA_LIST); + return; +} + + +int +dwarf_typename(Dwarf_Type type_in, char **ret_name, Dwarf_Error * error) +{ + Dwarf_Global type = (Dwarf_Global) type_in; + + if (type == NULL) { + _dwarf_error(NULL, error, DW_DLE_TYPE_NULL); + return (DW_DLV_ERROR); + } + + *ret_name = (char *) (type->gl_name); + return DW_DLV_OK; +} + + +int +dwarf_type_die_offset(Dwarf_Type type_in, + Dwarf_Off * ret_offset, Dwarf_Error * error) +{ + Dwarf_Global type = (Dwarf_Global) type_in; + + return dwarf_global_die_offset(type, ret_offset, error); +} + + +int +dwarf_type_cu_offset(Dwarf_Type type_in, + Dwarf_Off * ret_offset, Dwarf_Error * error) +{ + Dwarf_Global type = (Dwarf_Global) type_in; + + return dwarf_global_cu_offset(type, ret_offset, error); + +} + + +int +dwarf_type_name_offsets(Dwarf_Type type_in, + char **returned_name, + Dwarf_Off * die_offset, + Dwarf_Off * cu_die_offset, Dwarf_Error * error) +{ + Dwarf_Global type = (Dwarf_Global) type_in; + + return dwarf_global_name_offsets(type, + returned_name, + die_offset, cu_die_offset, error); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_types.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,41 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + + +typedef struct Dwarf_Type_Context_s *Dwarf_Type_Context; + +/* type never completed see dwarf_global.h */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_util.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_util.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,392 @@ +/* + Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_die_deliv.h" + + + +/* + Given a form, and a pointer to the bytes encoding + a value of that form, val_ptr, this function returns + the length, in bytes, of a value of that form. + When using this function, check for a return of 0 + a recursive DW_FORM_INDIRECT value. +*/ +Dwarf_Unsigned +_dwarf_get_size_of_val(Dwarf_Debug dbg, + Dwarf_Unsigned form, + Dwarf_Small * val_ptr, int v_length_size) +{ + Dwarf_Unsigned length = 0; + Dwarf_Word leb128_length = 0; + Dwarf_Unsigned form_indirect = 0; + Dwarf_Unsigned ret_value = 0; + + switch (form) { + + default: /* Handles form = 0. */ + return (form); + + case DW_FORM_addr: + return (dbg->de_pointer_size); + + case DW_FORM_ref_addr: + return (v_length_size); + + case DW_FORM_block1: + return (*(Dwarf_Small *) val_ptr + 1); + + case DW_FORM_block2: + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + val_ptr, sizeof(Dwarf_Half)); + return (ret_value + sizeof(Dwarf_Half)); + + case DW_FORM_block4: + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + val_ptr, sizeof(Dwarf_ufixed)); + return (ret_value + sizeof(Dwarf_ufixed)); + + + case DW_FORM_data1: + return (1); + + case DW_FORM_data2: + return (2); + + case DW_FORM_data4: + return (4); + + case DW_FORM_data8: + return (8); + + case DW_FORM_string: + return (strlen((char *) val_ptr) + 1); + + case DW_FORM_block: + length = _dwarf_decode_u_leb128(val_ptr, &leb128_length); + return (length + leb128_length); + + case DW_FORM_flag: + return (1); + + case DW_FORM_ref_udata: + _dwarf_decode_u_leb128(val_ptr, &leb128_length); + return (leb128_length); + + case DW_FORM_indirect: + { + Dwarf_Word indir_len = 0; + + form_indirect = _dwarf_decode_u_leb128(val_ptr, &indir_len); + if (form_indirect == DW_FORM_indirect) { + return (0); /* We are in big trouble: The true form + of DW_FORM_indirect is + DW_FORM_indirect? Nonsense. Should + never happen. */ + } + return (indir_len + _dwarf_get_size_of_val(dbg, + form_indirect, + val_ptr + + indir_len, + v_length_size)); + } + + case DW_FORM_ref1: + return (1); + + case DW_FORM_ref2: + return (2); + + case DW_FORM_ref4: + return (4); + + case DW_FORM_ref8: + return (8); + + case DW_FORM_sdata: + _dwarf_decode_s_leb128(val_ptr, &leb128_length); + return (leb128_length); + + case DW_FORM_strp: + return (v_length_size); + + case DW_FORM_udata: + _dwarf_decode_u_leb128(val_ptr, &leb128_length); + return (leb128_length); + } +} + + +/* + This function returns a pointer to a Dwarf_Abbrev_List_s + struct for the abbrev with the given code. It puts the + struct on the appropriate hash table. It also adds all + the abbrev between the last abbrev added and this one to + the hash table. In other words, the .debug_abbrev section + is scanned sequentially from the top for an abbrev with + the given code. All intervening abbrevs are also put + into the hash table. + + This function hashes the given code, and checks the chain + at that hash table entry to see if a Dwarf_Abbrev_List_s + with the given code exists. If yes, it returns a pointer + to that struct. Otherwise, it scans the .debug_abbrev + section from the last byte scanned for that CU till either + an abbrev with the given code is found, or an abbrev code + of 0 is read. It puts Dwarf_Abbrev_List_s entries for all + abbrev's read till that point into the hash table. The + hash table contains both a head pointer and a tail pointer + for each entry. + + Returns NULL on error. +*/ +Dwarf_Abbrev_List +_dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Word code) +{ + Dwarf_Debug dbg = cu_context->cc_dbg; + Dwarf_Hash_Table hash_table = cu_context->cc_abbrev_hash_table; + Dwarf_Word hash_num; + Dwarf_Abbrev_List hash_abbrev_list; + Dwarf_Abbrev_List abbrev_list; + Dwarf_Byte_Ptr abbrev_ptr; + Dwarf_Half abbrev_code, abbrev_tag; + Dwarf_Half attr_name, attr_form; + + hash_num = code % ABBREV_HASH_TABLE_SIZE; + for (hash_abbrev_list = hash_table[hash_num].at_head; + hash_abbrev_list != NULL && hash_abbrev_list->ab_code != code; + hash_abbrev_list = hash_abbrev_list->ab_next); + if (hash_abbrev_list != NULL) + return (hash_abbrev_list); + + abbrev_ptr = cu_context->cc_last_abbrev_ptr != NULL ? + cu_context->cc_last_abbrev_ptr : + dbg->de_debug_abbrev + cu_context->cc_abbrev_offset; + + /* End of abbrev's for this cu, since abbrev code is 0. */ + if (*abbrev_ptr == 0) { + return (NULL); + } + + do { + Dwarf_Unsigned utmp; + + DECODE_LEB128_UWORD(abbrev_ptr, utmp); + abbrev_code = (Dwarf_Half) utmp; + DECODE_LEB128_UWORD(abbrev_ptr, utmp); + abbrev_tag = (Dwarf_Half) utmp; + + abbrev_list = (Dwarf_Abbrev_List) + _dwarf_get_alloc(cu_context->cc_dbg, DW_DLA_ABBREV_LIST, 1); + if (abbrev_list == NULL) + return (NULL); + + hash_num = abbrev_code % ABBREV_HASH_TABLE_SIZE; + if (hash_table[hash_num].at_head == NULL) { + hash_table[hash_num].at_head = + hash_table[hash_num].at_tail = abbrev_list; + } else { + hash_table[hash_num].at_tail->ab_next = abbrev_list; + hash_table[hash_num].at_tail = abbrev_list; + } + + abbrev_list->ab_code = abbrev_code; + abbrev_list->ab_tag = abbrev_tag; + + abbrev_list->ab_has_child = *(abbrev_ptr++); + abbrev_list->ab_abbrev_ptr = abbrev_ptr; + + /* Cycle thru the abbrev content, ignoring the content except + to find the end of the content. */ + do { + Dwarf_Unsigned utmp3; + + DECODE_LEB128_UWORD(abbrev_ptr, utmp3); + attr_name = (Dwarf_Half) utmp3; + DECODE_LEB128_UWORD(abbrev_ptr, utmp3); + attr_form = (Dwarf_Half) utmp3; + } while (attr_name != 0 && attr_form != 0); + + } while (*abbrev_ptr != 0 && abbrev_code != code); + + cu_context->cc_last_abbrev_ptr = abbrev_ptr; + return (abbrev_code == code ? abbrev_list : NULL); +} + + +/* return 1 if string ends before 'endptr' else +** return 0 meaning string is not properly terminated. +** Presumption is the 'endptr' pts to end of some dwarf section data. +*/ +int +_dwarf_string_valid(void *startptr, void *endptr) +{ + + char *start = startptr; + char *end = endptr; + + while (start < end) { + if (*start == 0) { + return 1; /* OK! */ + } + ++start; + ++end; + } + return 0; /* FAIL! bad string! */ +} + +/* + A byte-swapping version of memcpy + for cross-endian use. + Only 2,4,8 should be lengths passed in. +*/ +void * +_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len) +{ + void *orig_s1 = s1; + unsigned char *targ = (unsigned char *) s1; + unsigned char *src = (unsigned char *) s2; + + if (len == 4) { + targ[3] = src[0]; + targ[2] = src[1]; + targ[1] = src[2]; + targ[0] = src[3]; + } else if (len == 8) { + targ[7] = src[0]; + targ[6] = src[1]; + targ[5] = src[2]; + targ[4] = src[3]; + targ[3] = src[4]; + targ[2] = src[5]; + targ[1] = src[6]; + targ[0] = src[7]; + } else if (len == 2) { + targ[1] = src[0]; + targ[0] = src[1]; + } +/* should NOT get below here: is not the intended use */ + else if (len == 1) { + targ[0] = src[0]; + } else { + memcpy(s1, s2, len); + } + + return orig_s1; +} + + +/* + This calculation used to be sprinkled all over. + Now brought to one place. + + We try to accurately compute the size of a cu header + given a known cu header location ( an offset in .debug_info). + +*/ +/* ARGSUSED */ +Dwarf_Unsigned +_dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset) +{ + int local_length_size = 0; + int local_extension_size = 0; + Dwarf_Unsigned length = 0; + Dwarf_Small *cuptr = dbg->de_debug_info + offset; + + READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, + cuptr, local_length_size, local_extension_size); + + return local_extension_size + /* initial extesion, if present + */ + local_length_size + /* Size of cu length field. */ + sizeof(Dwarf_Half) + /* Size of version stamp field. */ + local_length_size + /* Size of abbrev offset field. */ + sizeof(Dwarf_Small); /* Size of address size field. */ + +} + +/* + Pretend we know nothing about the CU + and just roughly compute the result. +*/ +Dwarf_Unsigned +_dwarf_length_of_cu_header_simple(Dwarf_Debug dbg) +{ + return dbg->de_length_size + /* Size of cu length field. */ + sizeof(Dwarf_Half) + /* Size of version stamp field. */ + dbg->de_length_size + /* Size of abbrev offset field. */ + sizeof(Dwarf_Small); /* Size of address size field. */ +} + +/* Now that we delay loading .debug_info, we need to do the + load in more places. So putting the load + code in one place now instead of replicating it in multiple + places. + +*/ +int +_dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error * error) +{ + int res; + + /* Testing de_debug_info allows us to avoid testing + de_debug_abbrev. One test instead of 2. .debug_info is useless + without .debug_abbrev. */ + if (dbg->de_debug_info) { + return DW_DLV_OK; + } + + res = _dwarf_load_section(dbg, dbg->de_debug_abbrev_index, + &dbg->de_debug_abbrev, error); + if (res != DW_DLV_OK) { + return res; + } + res = _dwarf_load_section(dbg, dbg->de_debug_info_index, + &dbg->de_debug_info, error); + return res; + +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_util.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_util.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,282 @@ +/* + + Copyright (C) 2000,2003,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + + + +/* + Decodes unsigned leb128 encoded numbers. + Make sure ptr is a pointer to a 1-byte type. + In 2003 and earlier this was a hand-inlined + version of _dwarf_decode_u_leb128() which did + not work correctly if Dwarf_Word was 64 bits. +*/ +#define DECODE_LEB128_UWORD(ptr, value) \ + do { \ + Dwarf_Word uleblen; \ + value = _dwarf_decode_u_leb128(ptr,&uleblen); \ + ptr += uleblen; \ + } while (0) + +/* + Decodes signed leb128 encoded numbers. + Make sure ptr is a pointer to a 1-byte type. + In 2003 and earlier this was a hand-inlined + version of _dwarf_decode_s_leb128() which did + not work correctly if Dwarf_Word was 64 bits. + +*/ +#define DECODE_LEB128_SWORD(ptr, value) \ + do { \ + Dwarf_Word sleblen; \ + value = _dwarf_decode_s_leb128(ptr,&sleblen); \ + ptr += sleblen; \ + } while(0) + + +/* + Skips leb128_encoded numbers that are guaranteed + to be no more than 4 bytes long. Same for both + signed and unsigned numbers. +*/ +#define SKIP_LEB128_WORD(ptr) \ + do{ if ((*(ptr++) & 0x80) != 0) { \ + if ((*(ptr++) & 0x80) != 0) { \ + if ((*(ptr++) & 0x80) != 0) { \ + if ((*(ptr++) & 0x80) != 0) { \ + } \ + } \ + } \ + } } while (0) + + +#define CHECK_DIE(die, error_ret_value) \ +do {if (die == NULL) { \ + _dwarf_error(NULL, error, DW_DLE_DIE_NULL); \ + return(error_ret_value); \ + } \ + if (die->di_cu_context == NULL) { \ + _dwarf_error(NULL, error, DW_DLE_DIE_NO_CU_CONTEXT); \ + return(error_ret_value); \ + } \ + if (die->di_cu_context->cc_dbg == NULL) { \ + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); \ + return(error_ret_value); \ + } \ +} while (0) + + +/* + Reads 'source' for 'length' bytes from unaligned addr. + + Avoids any constant-in-conditional warnings and + avoids a test in the generated code (for non-const cases, + which are in the majority.) + Uses a temp to avoid the test. + The decl here should avoid any problem of size in the temp. + This code is ENDIAN DEPENDENT + The memcpy args are the endian issue. +*/ +typedef Dwarf_Unsigned BIGGEST_UINT; + +#ifdef WORDS_BIGENDIAN +#define READ_UNALIGNED(dbg,dest,desttype, source, length) \ + do { \ + BIGGEST_UINT _ltmp = 0; \ + dbg->de_copy_word( (((char *)(&_ltmp)) + sizeof(_ltmp) - length), \ + source, length) ; \ + dest = (desttype)_ltmp; \ + } while (0) + + +/* + This macro sign-extends a variable depending on the length. + It fills the bytes between the size of the destination and + the length with appropriate padding. + This code is ENDIAN DEPENDENT but dependent only + on host endianness, not object file endianness. + The memcpy args are the issue. +*/ +#define SIGN_EXTEND(dest, length) \ + do {if (*(Dwarf_Sbyte *)((char *)&dest + sizeof(dest) - length) < 0) {\ + memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff", \ + sizeof(dest) - length); \ + } \ + } while (0) +#else /* LITTLE ENDIAN */ + +#define READ_UNALIGNED(dbg,dest,desttype, source, length) \ + do { \ + BIGGEST_UINT _ltmp = 0; \ + dbg->de_copy_word( (char *)(&_ltmp) , \ + source, length) ; \ + dest = (desttype)_ltmp; \ + } while (0) + + +/* + This macro sign-extends a variable depending on the length. + It fills the bytes between the size of the destination and + the length with appropriate padding. + This code is ENDIAN DEPENDENT but dependent only + on host endianness, not object file endianness. + The memcpy args are the issue. +*/ +#define SIGN_EXTEND(dest, length) \ + do {if (*(Dwarf_Sbyte *)((char *)&dest + (length-1)) < 0) {\ + memcpy((char *)&dest+length, \ + "\xff\xff\xff\xff\xff\xff\xff\xff", \ + sizeof(dest) - length); \ + } \ + } while (0) + +#endif /* ! LITTLE_ENDIAN */ + + + +/* + READ_AREA LENGTH reads the length (the older way + of pure 32 or 64 bit + or the new proposed dwarfv2.1 64bit-extension way) + + It reads the bits from where rw_src_data_p points to + and updates the rw_src_data_p to point past what was just read. + + It updates w_length_size and w_exten_size (which + are really issues only for the dwarfv2.1 64bit extension). + + r_dbg is just the current dbg pointer. + w_target is the output length field. + r_targtype is the output type. Always Dwarf_Unsigned so far. + +*/ +/* This one handles the v2.1 64bit extension + and 32bit (and MIPS fixed 64 bit via the + dwarf_init-set r_dbg->de_length_size).. + It does not recognize any but the one distingushed value + (the only one with defined meaning). + It assumes that no CU will have a length + 0xffffffxx (32bit length) + or + 0xffffffxx xxxxxxxx (64bit length) + which makes possible auto-detection of the extension. + + This depends on knowing that only a non-zero length + is legitimate (AFAICT), and for IRIX non-standard -64 + dwarf that the first 32 bits of the 64bit offset will be + zero (because the compiler could not handle a truly large + value as of Jan 2003 and because no app has that much debug + info anyway (yet)). + + At present not testing for '64bit elf' here as that + does not seem necessary (none of the 64bit length seems + appropriate unless it's ident[EI_CLASS] == ELFCLASS64). + Might be a good idea though. + +*/ +# define READ_AREA_LENGTH(r_dbg,w_target,r_targtype, \ + rw_src_data_p,w_length_size,w_exten_size) \ +do { READ_UNALIGNED(r_dbg,w_target,r_targtype, \ + rw_src_data_p, ORIGINAL_DWARF_OFFSET_SIZE); \ + if(w_target == DISTINGUISHED_VALUE) { \ + /* dwarf3 64bit extension */ \ + w_length_size = DISTINGUISHED_VALUE_OFFSET_SIZE; \ + rw_src_data_p += ORIGINAL_DWARF_OFFSET_SIZE; \ + w_exten_size = ORIGINAL_DWARF_OFFSET_SIZE; \ + READ_UNALIGNED(r_dbg,w_target,r_targtype, \ + rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE);\ + rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE; \ + } else { \ + if(w_target == 0 && r_dbg->de_big_endian_object) { \ + /* IRIX 64 bit, big endian */ \ + READ_UNALIGNED(r_dbg,w_target,r_targtype, \ + rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE); \ + w_length_size = DISTINGUISHED_VALUE_OFFSET_SIZE; \ + rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE; \ + w_exten_size = 0; \ + } else { \ + /* standard 32 bit dwarf2/dwarf3 */ \ + w_exten_size = 0; \ + w_length_size = ORIGINAL_DWARF_OFFSET_SIZE; \ + rw_src_data_p += w_length_size; \ + } \ + } } while(0) + + + +Dwarf_Unsigned +_dwarf_decode_u_leb128(Dwarf_Small * leb128, + Dwarf_Word * leb128_length); + +Dwarf_Signed +_dwarf_decode_s_leb128(Dwarf_Small * leb128, + Dwarf_Word * leb128_length); + +Dwarf_Unsigned +_dwarf_get_size_of_val(Dwarf_Debug dbg, + Dwarf_Unsigned form, + Dwarf_Small * val_ptr, int v_length_size); + +/* + This struct is used to build a hash table for the + abbreviation codes for a compile-unit. +*/ +struct Dwarf_Hash_Table_s { + Dwarf_Abbrev_List at_head; + Dwarf_Abbrev_List at_tail; +}; + +Dwarf_Abbrev_List +_dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, + Dwarf_Word code); + + +/* return 1 if string ends before 'endptr' else +** return 0 meaning string is not properly terminated. +** Presumption is the 'endptr' pts to end of some dwarf section data. +*/ +int _dwarf_string_valid(void *startptr, void *endptr); + +Dwarf_Unsigned _dwarf_length_of_cu_header(Dwarf_Debug, + Dwarf_Unsigned offset); +Dwarf_Unsigned _dwarf_length_of_cu_header_simple(Dwarf_Debug); + +int _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error *error); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_vars.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_vars.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,138 @@ +/* + + Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_vars.h" +#include "dwarf_global.h" + +int +dwarf_get_vars(Dwarf_Debug dbg, + Dwarf_Var ** vars, + Dwarf_Signed * ret_var_count, Dwarf_Error * error) +{ + int res; + + res = + _dwarf_load_section(dbg, + dbg->de_debug_varnames_index, + &dbg->de_debug_varnames, error); + if (res != DW_DLV_OK) { + return res; + } + + return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_varnames, dbg->de_debug_varnames_size, (Dwarf_Global **) vars, /* type + punning, + Dwarf_Type + is never a + completed + type */ + ret_var_count, + error, + DW_DLA_VAR_CONTEXT, + DW_DLA_VAR, + DW_DLE_DEBUG_VARNAMES_LENGTH_BAD, + DW_DLE_DEBUG_VARNAMES_VERSION_ERROR); +} + +/* Deallocating fully requires deallocating the list + and all entries. But some internal data is + not exposed, so we need a function with internal knowledge. +*/ + +void +dwarf_vars_dealloc(Dwarf_Debug dbg, Dwarf_Var * dwgl, + Dwarf_Signed count) +{ + _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl, + count, + DW_DLA_VAR_CONTEXT, + DW_DLA_VAR, DW_DLA_LIST); + return; +} + + +int +dwarf_varname(Dwarf_Var var_in, char **ret_varname, Dwarf_Error * error) +{ + Dwarf_Global var = (Dwarf_Global) var_in; + + if (var == NULL) { + _dwarf_error(NULL, error, DW_DLE_VAR_NULL); + return (DW_DLV_ERROR); + } + + *ret_varname = (char *) (var->gl_name); + return DW_DLV_OK; +} + + +int +dwarf_var_die_offset(Dwarf_Var var_in, + Dwarf_Off * returned_offset, Dwarf_Error * error) +{ + Dwarf_Global var = (Dwarf_Global) var_in; + + return dwarf_global_die_offset(var, returned_offset, error); + +} + + +int +dwarf_var_cu_offset(Dwarf_Var var_in, + Dwarf_Off * returned_offset, Dwarf_Error * error) +{ + Dwarf_Global var = (Dwarf_Global) var_in; + + return dwarf_global_cu_offset(var, returned_offset, error); +} + + +int +dwarf_var_name_offsets(Dwarf_Var var_in, + char **returned_name, + Dwarf_Off * die_offset, + Dwarf_Off * cu_offset, Dwarf_Error * error) +{ + Dwarf_Global var = (Dwarf_Global) var_in; + + return + dwarf_global_name_offsets(var, + returned_name, die_offset, cu_offset, + error); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_vars.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_vars.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,41 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + + +typedef struct Dwarf_Var_Context_s *Dwarf_Var_Context; + +/* struct never completed: see dwarf_global.h */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_weaks.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_weaks.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,140 @@ +/* + + Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_weaks.h" +#include "dwarf_global.h" + +int +dwarf_get_weaks(Dwarf_Debug dbg, + Dwarf_Weak ** weaks, + Dwarf_Signed * ret_weak_count, Dwarf_Error * error) +{ + int res; + + res = + _dwarf_load_section(dbg, + dbg->de_debug_weaknames_index, + &dbg->de_debug_weaknames, error); + if (res != DW_DLV_OK) { + return res; + } + + return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_weaknames, dbg->de_debug_weaknames_size, (Dwarf_Global **) weaks, /* type + punning, + Dwarf_Type + is + never + a + completed + type + */ + ret_weak_count, + error, + DW_DLA_WEAK_CONTEXT, + DW_DLA_WEAK, + DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD, + DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR); + +} + +/* Deallocating fully requires deallocating the list + and all entries. But some internal data is + not exposed, so we need a function with internal knowledge. +*/ + +void +dwarf_weaks_dealloc(Dwarf_Debug dbg, Dwarf_Weak * dwgl, + Dwarf_Signed count) +{ + _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl, + count, + DW_DLA_WEAK_CONTEXT, + DW_DLA_WEAK, DW_DLA_LIST); + return; +} + + + +int +dwarf_weakname(Dwarf_Weak weak_in, char **ret_name, Dwarf_Error * error) +{ + Dwarf_Global weak = (Dwarf_Global) weak_in; + + if (weak == NULL) { + _dwarf_error(NULL, error, DW_DLE_WEAK_NULL); + return (DW_DLV_ERROR); + } + *ret_name = (char *) (weak->gl_name); + return DW_DLV_OK; +} + + +int +dwarf_weak_die_offset(Dwarf_Weak weak_in, + Dwarf_Off * weak_off, Dwarf_Error * error) +{ + Dwarf_Global weak = (Dwarf_Global) weak_in; + + return dwarf_global_die_offset(weak, weak_off, error); +} + + +int +dwarf_weak_cu_offset(Dwarf_Weak weak_in, + Dwarf_Off * weak_off, Dwarf_Error * error) +{ + Dwarf_Global weak = (Dwarf_Global) weak_in; + + return dwarf_global_cu_offset(weak, weak_off, error); +} + + +int +dwarf_weak_name_offsets(Dwarf_Weak weak_in, + char **weak_name, + Dwarf_Off * die_offset, + Dwarf_Off * cu_offset, Dwarf_Error * error) +{ + Dwarf_Global weak = (Dwarf_Global) weak_in; + + return dwarf_global_name_offsets(weak, + weak_name, + die_offset, cu_offset, error); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_weaks.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_weaks.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,41 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + + +typedef struct Dwarf_Weak_Context_s *Dwarf_Weak_Context; + +/* struct never completed: see dwarf_global.h */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/index.v2.pdf Binary file tools/elf4rom/libs/dwarf-20071209/libdwarf/index.v2.pdf has changed diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/install.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/install.sh Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,119 @@ +#!/bin/sh + +# +# install - install a program, script, or datafile +# This comes from X11R5; it is not part of GNU. +# +# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" + +instcmd="$mvprog" +chmodcmd="" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +fi + +if [ x"$dst" = x ] +then + echo "install: no destination specified" + exit 1 +fi + + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + +if [ -d $dst ] +then + dst="$dst"/`basename $src` +fi + +# Make a temp file name in the proper directory. + +dstdir=`dirname $dst` +dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + +$doit $instcmd $src $dsttmp + +# and set any options; do chmod last to preserve setuid bits + +if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi +if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi +if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi +if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi + +# Now rename the file to the real destination. + +$doit $rmcmd $dst +$doit $mvcmd $dsttmp $dst + + +exit 0 diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,2117 @@ +/* + + Copyright (C) 2000,2001,2002,2005,2006 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + +#ifndef _LIBDWARF_H +#define _LIBDWARF_H +#ifdef __cplusplus +extern "C" { +#endif +/* + libdwarf.h + $Revision: 1.88 $ $Date: 2006/04/18 04:46:07 $ + + For libdwarf producers and consumers + + The interface is defined as having 8-byte signed and unsigned + values so it can handle 64-or-32bit target on 64-or-32bit host. + Addr is the native size: it represents pointers on + the host machine (not the target!). + + This contains declarations for types and all producer + and consumer functions. + + Function declarations are written on a single line each here + so one can use grep to each declaration in its entirety. + The declarations are a little harder to read this way, but... + +*/ + +#ifdef __SGI_FAST_LIBELF +struct elf_sgi; +typedef struct elf_sgi* dwarf_elf_handle; +#else +struct Elf; +typedef struct Elf* dwarf_elf_handle; +#endif + +#if (_MIPS_SZLONG == 64) +/* Special case for MIPS, so -64 (LP64) build gets simple -long-. + Non-MIPS LP64 or ILP64 environments should probably ensure + _MIPS_SZLONG set to 64 everywhere this header is #included. +*/ +typedef int Dwarf_Bool; /* boolean type */ +typedef unsigned long Dwarf_Off; /* 4 or 8 byte file offset */ +typedef unsigned long Dwarf_Unsigned; /* 4 or 8 byte unsigned value */ +typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */ +typedef unsigned char Dwarf_Small; /* 1 byte unsigned value */ +typedef signed long Dwarf_Signed; /* 4 or 8 byte signed value */ +typedef unsigned long Dwarf_Addr; /* target memory address */ +#else /* 32-bit */ +/* This is for ILP32, allowing i/o of 64bit dwarf info. + Also should be fine for LP64 and ILP64 cases. +*/ +typedef int Dwarf_Bool; /* boolean type */ +typedef unsigned long long Dwarf_Off; /* 8 byte file offset */ +typedef unsigned long long Dwarf_Unsigned; /* 8 byte unsigned value*/ +typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */ +typedef unsigned char Dwarf_Small; /* 1 byte unsigned value */ +typedef signed long long Dwarf_Signed; /* 8 byte signed value */ +typedef unsigned long long Dwarf_Addr; /* target memory address */ +#endif +typedef void* Dwarf_Ptr; /* host machine pointer */ + +/* Contains info on an uninterpreted block of data +*/ +typedef struct { + Dwarf_Unsigned bl_len; /* length of block */ + Dwarf_Ptr bl_data; /* uninterpreted data */ + Dwarf_Small bl_from_loclist; /*non-0 if loclist, else debug_info*/ + Dwarf_Unsigned bl_section_offset; /* Section (not CU) offset + which 'data' comes from. */ +} Dwarf_Block; + + +/* location record +*/ +typedef struct { + Dwarf_Small lr_atom; /* location operation */ + Dwarf_Unsigned lr_number; /* operand */ + Dwarf_Unsigned lr_number2; /* for OP_BREGx */ + Dwarf_Unsigned lr_offset; /* offset in locexpr for OP_BRA etc */ +} Dwarf_Loc; + + +/* location description +*/ +typedef struct { + Dwarf_Addr ld_lopc; /* beginning of active range */ + Dwarf_Addr ld_hipc; /* end of active range */ + Dwarf_Half ld_cents; /* count of location records */ + Dwarf_Loc* ld_s; /* pointer to list of same */ + Dwarf_Small ld_from_loclist; + /* non-0 if loclist, else debug_info*/ + + Dwarf_Unsigned ld_section_offset; /* Section (not CU) offset + where loc-expr begins*/ +} Dwarf_Locdesc; + +/* Frame description instructions expanded. +*/ +typedef struct { + Dwarf_Small fp_base_op; + Dwarf_Small fp_extended_op; + Dwarf_Half fp_register; + + /* Value may be signed, depends on op. + Any applicable data_alignment_factor has + not been applied, this is the raw offset. */ + Dwarf_Unsigned fp_offset; + Dwarf_Off fp_instr_offset; +} Dwarf_Frame_Op; /* DWARF2 */ + +typedef struct { + Dwarf_Small fp_base_op; + Dwarf_Small fp_extended_op; + Dwarf_Half fp_register; + + /* Value may be signed, depends on op. + Any applicable data_alignment_factor has + not been applied, this is the raw offset. */ + Dwarf_Unsigned fp_offset_or_block_len; + Dwarf_Small *fp_expr_block; + + Dwarf_Off fp_instr_offset; +} Dwarf_Frame_Op3; /* DWARF3 and DWARF2 compatible */ + +/* ***IMPORTANT NOTE, TARGET DEPENDENCY **** + DW_REG_TABLE_SIZE must be at least as large as + the number of registers + (DW_FRAME_LAST_REG_NUM) as defined in dwarf.h + Preferably identical to DW_FRAME_LAST_REG_NUM. + Ensure [0-DW_REG_TABLE_SIZE] does not overlap + DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL. + Also ensure DW_FRAME_REG_INITIAL_VALUE is set to what + is appropriate to your cpu. + For various CPUs DW_FRAME_UNDEFINED_VAL is correct + as the value for DW_FRAME_REG_INITIAL_VALUE. + + For consumer apps, this can be set dynamically: see + dwarf_set_frame_rule_table_size(); + */ +#ifndef DW_REG_TABLE_SIZE +#define DW_REG_TABLE_SIZE 66 +#endif + +/* For MIPS, DW_FRAME_SAME_VAL is the correct default value + for a frame register value. For other CPUS another value + may be better, such as DW_FRAME_UNDEFINED_VAL. + See dwarf_set_frame_rule_table_size +*/ +#ifndef DW_FRAME_REG_INITIAL_VALUE +#define DW_FRAME_REG_INITIAL_VALUE DW_FRAME_SAME_VAL +#endif + +/* Taken as meaning 'undefined value', this is not + a column or register number. + Only present at libdwarf runtime. Never on disk. + DW_FRAME_* Values present on disk are in dwarf.h + Ensure this is > DW_REG_TABLE_SIZE. +*/ +#define DW_FRAME_UNDEFINED_VAL 1034 + +/* Taken as meaning 'same value' as caller had, not a column + or register number + Only present at libdwarf runtime. Never on disk. + DW_FRAME_* Values present on disk are in dwarf.h + Ensure this is > DW_REG_TABLE_SIZE. +*/ +#define DW_FRAME_SAME_VAL 1035 + +/* For DWARF3 interfaces, make the CFA a column with no + real table number. This is what should have been done + for the DWARF2 interfaces. This actually works for + both DWARF2 and DWARF3, but see the libdwarf documentation + on Dwarf_Regtable3 and dwarf_get_fde_info_for_reg3() + and dwarf_get_fde_info_for_all_regs3() + Do NOT use this with the older dwarf_get_fde_info_for_reg() + or dwarf_get_fde_info_for_all_regs() consumer interfaces. +*/ +#define DW_FRAME_CFA_COL3 1036 + +/* The following are all needed to evaluate DWARF3 register rules. +*/ +#define DW_EXPR_OFFSET 0 /* DWARF2 only sees this. */ +#define DW_EXPR_VAL_OFFSET 1 +#define DW_EXPR_EXPRESSION 2 +#define DW_EXPR_VAL_EXPRESSION 3 + +typedef struct Dwarf_Regtable_Entry_s { + /* For each index i (naming a hardware register with dwarf number + i) the following is true and defines the value of that register: + + If dw_regnum is Register DW_FRAME_UNDEFINED_VAL + it is not DWARF register number but + a place holder indicating the register has no defined value. + If dw_regnum is Register DW_FRAME_SAME_VAL + it is not DWARF register number but + a place holder indicating the register has the same + value in the previous frame. + DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL are + only present at libdwarf runtime. Never on disk. + DW_FRAME_* Values present on disk are in dwarf.h + + Otherwise: the register number is a DWARF register number + (see ABI documents for how this translates to hardware/ + software register numbers in the machine hardware) + and the following applies: + + if dw_value_type == DW_EXPR_OFFSET (the only possible case for dwarf2): + If dw_offset_relevant is non-zero, then + the value is stored at at the address CFA+N where N is a signed offset. + Rule: Offset(N) + If dw_offset_relevant is zero, then the value of the register + is the value of (DWARF) register number dw_regnum. + Rule: register(F) + Other values of dw_value_type are an error. + */ + Dwarf_Small dw_offset_relevant; + + /* For DWARF2, always 0 */ + Dwarf_Small dw_value_type; + + Dwarf_Half dw_regnum; + + /* The data type here should the larger of Dwarf_Addr + and Dwarf_Unsigned and Dwarf_Signed. */ + Dwarf_Addr dw_offset; +} Dwarf_Regtable_Entry; + +typedef struct Dwarf_Regtable_s { + struct Dwarf_Regtable_Entry_s rules[DW_REG_TABLE_SIZE]; +} Dwarf_Regtable; + +/* opaque type. Functional interface shown later. */ +struct Dwarf_Reg_value3_s; +typedef struct Dwarf_Reg_value3_s Dwarf_Reg_Value3; + +typedef struct Dwarf_Regtable_Entry3_s { + /* For each index i (naming a hardware register with dwarf number + i) the following is true and defines the value of that register: + + If dw_regnum is Register DW_FRAME_UNDEFINED_VAL + it is not DWARF register number but + a place holder indicating the register has no defined value. + If dw_regnum is Register DW_FRAME_SAME_VAL + it is not DWARF register number but + a place holder indicating the register has the same + value in the previous frame. + DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL are + only present at libdwarf runtime. Never on disk. + DW_FRAME_* Values present on disk are in dwarf.h + + Otherwise: the register number is a DWARF register number + (see ABI documnets for how this translates to hardware/ + software register numbers in the machine hardware) + and the following applies: + + if dw_value_type == DW_EXPR_OFFSET (the only possible case for + dwarf2): + If dw_offset_relevant is non-zero, then + the value is stored at at the address + CFA+N where N is a signed offset. + Rule: Offset(N) + If dw_offset_relevant is zero, then the value of the register + is the value of (DWARF) register number dw_regnum. + Rule: register(R) + if dw_value_type == DW_EXPR_VAL_OFFSET + the value of this register is CFA +N where N is a signed offset. + Rule: val_offset(N) + + if dw_value_type == DW_EXPR_EXPRESSION + The value of the register is the value at the address + computed by evaluating the DWARF expression E. + Rule: expression(E) + The expression E byte stream is pointed to by dw_block_ptr. + The expression length in bytes is given by + dw_offset_or_block_len. + if dw_value_type == DW_EXPR_VAL_EXPRESSION + The value of the register is the value + computed by evaluating the DWARF expression E. + Rule: val_expression(E) + The expression E byte stream is pointed to by dw_block_ptr. + The expression length in bytes is given by + dw_offset_or_block_len. + Other values of dw_value_type are an error. + */ + Dwarf_Small dw_offset_relevant; + Dwarf_Small dw_value_type; + Dwarf_Half dw_regnum; + Dwarf_Unsigned dw_offset_or_block_len; + Dwarf_Ptr dw_block_ptr; + +}Dwarf_Regtable_Entry3; + +/* For the DWARF3 version, moved the DW_FRAME_CFA_COL + out of the array and into its own struct. + Having it part of the array is not very easy to work + with from a portability point of view: changing + the number for every architecture is a pain (if one fails + to set it correctly a register rule gets clobbered when + setting CFA). + With MIPS it just happened to be easy to use DW_FRAME_CFA_COL. + + rt3_rules and rt3_reg_table_size must be filled in + before calling libdwarf. + Filled in with a pointer to an array (pointer and + array set up by the calling application) of rt3_reg_table_size + Dwarf_Regtable_Entry3_s structs. + libdwarf does not allocate or deallocate space for the + rules, you must do so. libdwarf will initialize the + contents rules array, you do not need to do so (though + if you choose to initialize the array somehow that is ok: + libdwarf will overwrite your initializations with its own). + +*/ +typedef struct Dwarf_Regtable3_s { + struct Dwarf_Regtable_Entry3_s rt3_cfa_rule; + + Dwarf_Half rt3_reg_table_size; + struct Dwarf_Regtable_Entry3_s * rt3_rules; +} Dwarf_Regtable3; + + +/* Use for DW_EPXR_STANDARD., DW_EXPR_VAL_OFFSET. + Returns DW_DLV_OK if the value is available. + If DW_DLV_OK returns the regnum and offset thru the pointers + (which the consumer must use appropriately). +*/ +int dwarf_frame_get_reg_register(struct Dwarf_Regtable_Entry3_s *reg_in, + Dwarf_Small *offset_relevant, + Dwarf_Half *regnum_out, + Dwarf_Signed *offset_out); + +/* Use for DW_EXPR_EXPRESSION, DW_EXPR_VAL_EXPRESSION. + Returns DW_DLV_OK if the value is available. + The caller must pass in the address of a valid + Dwarf_Block (the caller need not initialize it). +*/ +int dwarf_frame_get_reg_expression(struct Dwarf_Regtable_Entry3_s *reg_in, + Dwarf_Block *block_out); + + +/* for DW_DLC_SYMBOLIC_RELOCATIONS output to caller + v2, adding drd_length: some relocations are 4 and + some 8 bytes (pointers are 8, section offsets 4) in + some dwarf environments. (MIPS relocations are all one + size in any given ABI.) Changing drd_type to an unsigned char + to keep struct size down. +*/ +enum Dwarf_Rel_Type { + dwarf_drt_none, /* should not get to caller */ + dwarf_drt_data_reloc, /* simple normal relocation */ + dwarf_drt_segment_rel, /* special reloc, exceptions*/ + dwarf_drt_first_of_length_pair,/* this and drt_second + for .word end - begin + case */ + dwarf_drt_second_of_length_pair +}; + +typedef struct Dwarf_P_Marker_s * Dwarf_P_Marker; +struct Dwarf_P_Marker_s { + Dwarf_Unsigned ma_marker; + Dwarf_Unsigned ma_offset; +}; + +typedef struct Dwarf_Relocation_Data_s * Dwarf_Relocation_Data; +struct Dwarf_Relocation_Data_s { + unsigned char drd_type; /* cast to/from Dwarf_Rel_Type + to keep size small in struct */ + unsigned char drd_length; /* length in bytes + of data being relocated. 4 for 32bit. + 8 for 64bit data */ + Dwarf_Unsigned drd_offset; /* where the data to reloc is */ + Dwarf_Unsigned drd_symbol_index; +}; + +typedef struct Dwarf_P_String_Attr_s * Dwarf_P_String_Attr; +struct Dwarf_P_String_Attr_s { + Dwarf_Unsigned sa_offset; /* Offset of string attribute data */ + Dwarf_Unsigned sa_nbytes; +}; + + +/* Opaque types for Consumer Library. */ +typedef struct Dwarf_Debug_s* Dwarf_Debug; +typedef struct Dwarf_Die_s* Dwarf_Die; +typedef struct Dwarf_Line_s* Dwarf_Line; +typedef struct Dwarf_Global_s* Dwarf_Global; +typedef struct Dwarf_Func_s* Dwarf_Func; +typedef struct Dwarf_Type_s* Dwarf_Type; +typedef struct Dwarf_Var_s* Dwarf_Var; +typedef struct Dwarf_Weak_s* Dwarf_Weak; +typedef struct Dwarf_Error_s* Dwarf_Error; +typedef struct Dwarf_Attribute_s* Dwarf_Attribute; +typedef struct Dwarf_Abbrev_s* Dwarf_Abbrev; +typedef struct Dwarf_Fde_s* Dwarf_Fde; +typedef struct Dwarf_Cie_s* Dwarf_Cie; +typedef struct Dwarf_Arange_s* Dwarf_Arange; + +/* Opaque types for Producer Library. */ +typedef struct Dwarf_P_Debug_s* Dwarf_P_Debug; +typedef struct Dwarf_P_Die_s* Dwarf_P_Die; +typedef struct Dwarf_P_Attribute_s* Dwarf_P_Attribute; +typedef struct Dwarf_P_Fde_s* Dwarf_P_Fde; +typedef struct Dwarf_P_Expr_s* Dwarf_P_Expr; +typedef Dwarf_Unsigned Dwarf_Tag; + + +/* error handler function +*/ +typedef void (*Dwarf_Handler)(Dwarf_Error /*error*/, Dwarf_Ptr /*errarg*/); + + +/* + Dwarf_dealloc() alloc_type arguments. + Argument points to: +*/ +#define DW_DLA_STRING 0x01 /* char* */ +#define DW_DLA_LOC 0x02 /* Dwarf_Loc */ +#define DW_DLA_LOCDESC 0x03 /* Dwarf_Locdesc */ +#define DW_DLA_ELLIST 0x04 /* Dwarf_Ellist (not used)*/ +#define DW_DLA_BOUNDS 0x05 /* Dwarf_Bounds (not used) */ +#define DW_DLA_BLOCK 0x06 /* Dwarf_Block */ +#define DW_DLA_DEBUG 0x07 /* Dwarf_Debug */ +#define DW_DLA_DIE 0x08 /* Dwarf_Die */ +#define DW_DLA_LINE 0x09 /* Dwarf_Line */ +#define DW_DLA_ATTR 0x0a /* Dwarf_Attribute */ +#define DW_DLA_TYPE 0x0b /* Dwarf_Type (not used) */ +#define DW_DLA_SUBSCR 0x0c /* Dwarf_Subscr (not used) */ +#define DW_DLA_GLOBAL 0x0d /* Dwarf_Global */ +#define DW_DLA_ERROR 0x0e /* Dwarf_Error */ +#define DW_DLA_LIST 0x0f /* a list */ +#define DW_DLA_LINEBUF 0x10 /* Dwarf_Line* (not used) */ +#define DW_DLA_ARANGE 0x11 /* Dwarf_Arange */ +#define DW_DLA_ABBREV 0x12 /* Dwarf_Abbrev */ +#define DW_DLA_FRAME_OP 0x13 /* Dwarf_Frame_Op */ +#define DW_DLA_CIE 0x14 /* Dwarf_Cie */ +#define DW_DLA_FDE 0x15 /* Dwarf_Fde */ +#define DW_DLA_LOC_BLOCK 0x16 /* Dwarf_Loc Block (not used) */ +#define DW_DLA_FRAME_BLOCK 0x17 /* Dwarf_Frame Block (not used) */ +#define DW_DLA_FUNC 0x18 /* Dwarf_Func */ +#define DW_DLA_TYPENAME 0x19 /* Dwarf_Type */ +#define DW_DLA_VAR 0x1a /* Dwarf_Var */ +#define DW_DLA_WEAK 0x1b /* Dwarf_Weak */ +#define DW_DLA_ADDR 0x1c /* Dwarf_Addr sized entries */ + +/* The augmenter string for CIE */ +#define DW_CIE_AUGMENTER_STRING_V0 "z" + +/* dwarf_init() access arguments +*/ +#define DW_DLC_READ 0 /* read only access */ +#define DW_DLC_WRITE 1 /* write only access */ +#define DW_DLC_RDWR 2 /* read/write access NOT SUPPORTED*/ + +/* dwarf_init() access flag modifiers +*/ +#define DW_DLC_SIZE_64 0x40000000 /* 32-bit target */ +#define DW_DLC_SIZE_32 0x20000000 /* 64-bit target */ + +/* dwarf_init() access flag modifiers +*/ +#define DW_DLC_ISA_MIPS 0x00000000 /* MIPS target */ +#define DW_DLC_ISA_IA64 0x01000000 /* IA64 target */ +#define DW_DLC_STREAM_RELOCATIONS 0x02000000 /* old style binary relocs */ +#define DW_DLC_SYMBOLIC_RELOCATIONS 0x04000000 /* usable with assem output */ +#define DW_DLC_TARGET_BIGENDIAN 0x08000000 /* big endian target */ +#define DW_DLC_TARGET_LITTLEENDIAN 0x00100000 /* little endian target */ + +#if 0 + /* + The libdwarf producer interfaces jumble these two semantics together in + confusing ways. We *should* have flags like these... + But changing the code means a lot of diffs. So for now, + we leave things as they are + */ + #define DW_DLC_SUN_OFFSET32 0x00010000 /* use 32-bit sec offsets */ + #define DW_DLC_SUN_OFFSET64 0x00020000 /* use 64-bit sec offsets */ + #define DW_DLC_SUN_POINTER32 0x00040000 /* use 4 for address_size */ + #define DW_DLC_SUN_POINTER64 0x00080000 /* use 8 for address_size */ +#endif + +/* dwarf_pcline() slide arguments +*/ +#define DW_DLS_BACKWARD -1 /* slide backward to find line */ +#define DW_DLS_NOSLIDE 0 /* match exactly without sliding */ +#define DW_DLS_FORWARD 1 /* slide forward to find line */ + +/* libdwarf error numbers +*/ +#define DW_DLE_NE 0 /* no error */ +#define DW_DLE_VMM 1 /* dwarf format/library version mismatch */ +#define DW_DLE_MAP 2 /* memory map failure */ +#define DW_DLE_LEE 3 /* libelf error */ +#define DW_DLE_NDS 4 /* no debug section */ +#define DW_DLE_NLS 5 /* no line section */ +#define DW_DLE_ID 6 /* invalid descriptor for query */ +#define DW_DLE_IOF 7 /* I/O failure */ +#define DW_DLE_MAF 8 /* memory allocation failure */ +#define DW_DLE_IA 9 /* invalid argument */ +#define DW_DLE_MDE 10 /* mangled debugging entry */ +#define DW_DLE_MLE 11 /* mangled line number entry */ +#define DW_DLE_FNO 12 /* file not open */ +#define DW_DLE_FNR 13 /* file not a regular file */ +#define DW_DLE_FWA 14 /* file open with wrong access */ +#define DW_DLE_NOB 15 /* not an object file */ +#define DW_DLE_MOF 16 /* mangled object file header */ +#define DW_DLE_EOLL 17 /* end of location list entries */ +#define DW_DLE_NOLL 18 /* no location list section */ +#define DW_DLE_BADOFF 19 /* Invalid offset */ +#define DW_DLE_EOS 20 /* end of section */ +#define DW_DLE_ATRUNC 21 /* abbreviations section appears truncated*/ +#define DW_DLE_BADBITC 22 /* Address size passed to dwarf bad*/ + /* It is not an allowed size (64 or 32) */ + /* Error codes defined by the current Libdwarf Implementation. */ +#define DW_DLE_DBG_ALLOC 23 +#define DW_DLE_FSTAT_ERROR 24 +#define DW_DLE_FSTAT_MODE_ERROR 25 +#define DW_DLE_INIT_ACCESS_WRONG 26 +#define DW_DLE_ELF_BEGIN_ERROR 27 +#define DW_DLE_ELF_GETEHDR_ERROR 28 +#define DW_DLE_ELF_GETSHDR_ERROR 29 +#define DW_DLE_ELF_STRPTR_ERROR 30 +#define DW_DLE_DEBUG_INFO_DUPLICATE 31 +#define DW_DLE_DEBUG_INFO_NULL 32 +#define DW_DLE_DEBUG_ABBREV_DUPLICATE 33 +#define DW_DLE_DEBUG_ABBREV_NULL 34 +#define DW_DLE_DEBUG_ARANGES_DUPLICATE 35 +#define DW_DLE_DEBUG_ARANGES_NULL 36 +#define DW_DLE_DEBUG_LINE_DUPLICATE 37 +#define DW_DLE_DEBUG_LINE_NULL 38 +#define DW_DLE_DEBUG_LOC_DUPLICATE 39 +#define DW_DLE_DEBUG_LOC_NULL 40 +#define DW_DLE_DEBUG_MACINFO_DUPLICATE 41 +#define DW_DLE_DEBUG_MACINFO_NULL 42 +#define DW_DLE_DEBUG_PUBNAMES_DUPLICATE 43 +#define DW_DLE_DEBUG_PUBNAMES_NULL 44 +#define DW_DLE_DEBUG_STR_DUPLICATE 45 +#define DW_DLE_DEBUG_STR_NULL 46 +#define DW_DLE_CU_LENGTH_ERROR 47 +#define DW_DLE_VERSION_STAMP_ERROR 48 +#define DW_DLE_ABBREV_OFFSET_ERROR 49 +#define DW_DLE_ADDRESS_SIZE_ERROR 50 +#define DW_DLE_DEBUG_INFO_PTR_NULL 51 +#define DW_DLE_DIE_NULL 52 +#define DW_DLE_STRING_OFFSET_BAD 53 +#define DW_DLE_DEBUG_LINE_LENGTH_BAD 54 +#define DW_DLE_LINE_PROLOG_LENGTH_BAD 55 +#define DW_DLE_LINE_NUM_OPERANDS_BAD 56 +#define DW_DLE_LINE_SET_ADDR_ERROR 57 +#define DW_DLE_LINE_EXT_OPCODE_BAD 58 +#define DW_DLE_DWARF_LINE_NULL 59 +#define DW_DLE_INCL_DIR_NUM_BAD 60 +#define DW_DLE_LINE_FILE_NUM_BAD 61 +#define DW_DLE_ALLOC_FAIL 62 +#define DW_DLE_NO_CALLBACK_FUNC 63 +#define DW_DLE_SECT_ALLOC 64 +#define DW_DLE_FILE_ENTRY_ALLOC 65 +#define DW_DLE_LINE_ALLOC 66 +#define DW_DLE_FPGM_ALLOC 67 +#define DW_DLE_INCDIR_ALLOC 68 +#define DW_DLE_STRING_ALLOC 69 +#define DW_DLE_CHUNK_ALLOC 70 +#define DW_DLE_BYTEOFF_ERR 71 +#define DW_DLE_CIE_ALLOC 72 +#define DW_DLE_FDE_ALLOC 73 +#define DW_DLE_REGNO_OVFL 74 +#define DW_DLE_CIE_OFFS_ALLOC 75 +#define DW_DLE_WRONG_ADDRESS 76 +#define DW_DLE_EXTRA_NEIGHBORS 77 +#define DW_DLE_WRONG_TAG 78 +#define DW_DLE_DIE_ALLOC 79 +#define DW_DLE_PARENT_EXISTS 80 +#define DW_DLE_DBG_NULL 81 +#define DW_DLE_DEBUGLINE_ERROR 82 +#define DW_DLE_DEBUGFRAME_ERROR 83 +#define DW_DLE_DEBUGINFO_ERROR 84 +#define DW_DLE_ATTR_ALLOC 85 +#define DW_DLE_ABBREV_ALLOC 86 +#define DW_DLE_OFFSET_UFLW 87 +#define DW_DLE_ELF_SECT_ERR 88 +#define DW_DLE_DEBUG_FRAME_LENGTH_BAD 89 +#define DW_DLE_FRAME_VERSION_BAD 90 +#define DW_DLE_CIE_RET_ADDR_REG_ERROR 91 +#define DW_DLE_FDE_NULL 92 +#define DW_DLE_FDE_DBG_NULL 93 +#define DW_DLE_CIE_NULL 94 +#define DW_DLE_CIE_DBG_NULL 95 +#define DW_DLE_FRAME_TABLE_COL_BAD 96 +#define DW_DLE_PC_NOT_IN_FDE_RANGE 97 +#define DW_DLE_CIE_INSTR_EXEC_ERROR 98 +#define DW_DLE_FRAME_INSTR_EXEC_ERROR 99 +#define DW_DLE_FDE_PTR_NULL 100 +#define DW_DLE_RET_OP_LIST_NULL 101 +#define DW_DLE_LINE_CONTEXT_NULL 102 +#define DW_DLE_DBG_NO_CU_CONTEXT 103 +#define DW_DLE_DIE_NO_CU_CONTEXT 104 +#define DW_DLE_FIRST_DIE_NOT_CU 105 +#define DW_DLE_NEXT_DIE_PTR_NULL 106 +#define DW_DLE_DEBUG_FRAME_DUPLICATE 107 +#define DW_DLE_DEBUG_FRAME_NULL 108 +#define DW_DLE_ABBREV_DECODE_ERROR 109 +#define DW_DLE_DWARF_ABBREV_NULL 110 +#define DW_DLE_ATTR_NULL 111 +#define DW_DLE_DIE_BAD 112 +#define DW_DLE_DIE_ABBREV_BAD 113 +#define DW_DLE_ATTR_FORM_BAD 114 +#define DW_DLE_ATTR_NO_CU_CONTEXT 115 +#define DW_DLE_ATTR_FORM_SIZE_BAD 116 +#define DW_DLE_ATTR_DBG_NULL 117 +#define DW_DLE_BAD_REF_FORM 118 +#define DW_DLE_ATTR_FORM_OFFSET_BAD 119 +#define DW_DLE_LINE_OFFSET_BAD 120 +#define DW_DLE_DEBUG_STR_OFFSET_BAD 121 +#define DW_DLE_STRING_PTR_NULL 122 +#define DW_DLE_PUBNAMES_VERSION_ERROR 123 +#define DW_DLE_PUBNAMES_LENGTH_BAD 124 +#define DW_DLE_GLOBAL_NULL 125 +#define DW_DLE_GLOBAL_CONTEXT_NULL 126 +#define DW_DLE_DIR_INDEX_BAD 127 +#define DW_DLE_LOC_EXPR_BAD 128 +#define DW_DLE_DIE_LOC_EXPR_BAD 129 +#define DW_DLE_ADDR_ALLOC 130 +#define DW_DLE_OFFSET_BAD 131 +#define DW_DLE_MAKE_CU_CONTEXT_FAIL 132 +#define DW_DLE_REL_ALLOC 133 +#define DW_DLE_ARANGE_OFFSET_BAD 134 +#define DW_DLE_SEGMENT_SIZE_BAD 135 +#define DW_DLE_ARANGE_LENGTH_BAD 136 +#define DW_DLE_ARANGE_DECODE_ERROR 137 +#define DW_DLE_ARANGES_NULL 138 +#define DW_DLE_ARANGE_NULL 139 +#define DW_DLE_NO_FILE_NAME 140 +#define DW_DLE_NO_COMP_DIR 141 +#define DW_DLE_CU_ADDRESS_SIZE_BAD 142 +#define DW_DLE_INPUT_ATTR_BAD 143 +#define DW_DLE_EXPR_NULL 144 +#define DW_DLE_BAD_EXPR_OPCODE 145 +#define DW_DLE_EXPR_LENGTH_BAD 146 +#define DW_DLE_MULTIPLE_RELOC_IN_EXPR 147 +#define DW_DLE_ELF_GETIDENT_ERROR 148 +#define DW_DLE_NO_AT_MIPS_FDE 149 +#define DW_DLE_NO_CIE_FOR_FDE 150 +#define DW_DLE_DIE_ABBREV_LIST_NULL 151 +#define DW_DLE_DEBUG_FUNCNAMES_DUPLICATE 152 +#define DW_DLE_DEBUG_FUNCNAMES_NULL 153 +#define DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR 154 +#define DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD 155 +#define DW_DLE_FUNC_NULL 156 +#define DW_DLE_FUNC_CONTEXT_NULL 157 +#define DW_DLE_DEBUG_TYPENAMES_DUPLICATE 158 +#define DW_DLE_DEBUG_TYPENAMES_NULL 159 +#define DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR 160 +#define DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD 161 +#define DW_DLE_TYPE_NULL 162 +#define DW_DLE_TYPE_CONTEXT_NULL 163 +#define DW_DLE_DEBUG_VARNAMES_DUPLICATE 164 +#define DW_DLE_DEBUG_VARNAMES_NULL 165 +#define DW_DLE_DEBUG_VARNAMES_VERSION_ERROR 166 +#define DW_DLE_DEBUG_VARNAMES_LENGTH_BAD 167 +#define DW_DLE_VAR_NULL 168 +#define DW_DLE_VAR_CONTEXT_NULL 169 +#define DW_DLE_DEBUG_WEAKNAMES_DUPLICATE 170 +#define DW_DLE_DEBUG_WEAKNAMES_NULL 171 +#define DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR 172 +#define DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD 173 +#define DW_DLE_WEAK_NULL 174 +#define DW_DLE_WEAK_CONTEXT_NULL 175 +#define DW_DLE_LOCDESC_COUNT_WRONG 176 +#define DW_DLE_MACINFO_STRING_NULL 177 +#define DW_DLE_MACINFO_STRING_EMPTY 178 +#define DW_DLE_MACINFO_INTERNAL_ERROR_SPACE 179 +#define DW_DLE_MACINFO_MALLOC_FAIL 180 +#define DW_DLE_DEBUGMACINFO_ERROR 181 +#define DW_DLE_DEBUG_MACRO_LENGTH_BAD 182 +#define DW_DLE_DEBUG_MACRO_MAX_BAD 183 +#define DW_DLE_DEBUG_MACRO_INTERNAL_ERR 184 +#define DW_DLE_DEBUG_MACRO_MALLOC_SPACE 185 +#define DW_DLE_DEBUG_MACRO_INCONSISTENT 186 +#define DW_DLE_DF_NO_CIE_AUGMENTATION 187 +#define DW_DLE_DF_REG_NUM_TOO_HIGH 188 +#define DW_DLE_DF_MAKE_INSTR_NO_INIT 189 +#define DW_DLE_DF_NEW_LOC_LESS_OLD_LOC 190 +#define DW_DLE_DF_POP_EMPTY_STACK 191 +#define DW_DLE_DF_ALLOC_FAIL 192 +#define DW_DLE_DF_FRAME_DECODING_ERROR 193 +#define DW_DLE_DEBUG_LOC_SECTION_SHORT 194 +#define DW_DLE_FRAME_AUGMENTATION_UNKNOWN 195 +#define DW_DLA_PUBTYPE_CONTEXT 196 +#define DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD 197 +#define DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR 198 +#define DW_DLE_DEBUG_PUBTYPES_DUPLICATE 199 +#define DW_DLE_FRAME_CIE_DECODE_ERROR 200 +#define DW_DLE_FRAME_REGISTER_UNREPRESENTABLE 201 +#define DW_DLE_FRAME_REGISTER_COUNT_MISMATCH 202 +#define DW_DLE_LINK_LOOP 203 + + + + /* DW_DLE_LAST MUST EQUAL LAST ERROR NUMBER */ +#define DW_DLE_LAST 203 +#define DW_DLE_LO_USER 0x10000 + + /* taken as meaning 'undefined value', this is not + a column or register number. + Only present at libdwarf runtime. Never on disk. + DW_FRAME_* Values present on disk are in dwarf.h + */ +#define DW_FRAME_UNDEFINED_VAL 1034 + + /* taken as meaning 'same value' as caller had, not a column + or register number + Only present at libdwarf runtime. Never on disk. + DW_FRAME_* Values present on disk are in dwarf.h + */ +#define DW_FRAME_SAME_VAL 1035 + + + +/* error return values +*/ +#define DW_DLV_BADADDR (~(Dwarf_Addr)0) + /* for functions returning target address */ + +#define DW_DLV_NOCOUNT ((Dwarf_Signed)-1) + /* for functions returning count */ + +#define DW_DLV_BADOFFSET (~(Dwarf_Off)0) + /* for functions returning offset */ + +/* standard return values for functions */ +#define DW_DLV_NO_ENTRY -1 +#define DW_DLV_OK 0 +#define DW_DLV_ERROR 1 + +/* Special values for offset_into_exception_table field of dwarf fde's. */ +/* The following value indicates that there is no Exception table offset + associated with a dwarf frame. */ +#define DW_DLX_NO_EH_OFFSET (-1LL) +/* The following value indicates that the producer was unable to analyse the + source file to generate Exception tables for this function. */ +#define DW_DLX_EH_OFFSET_UNAVAILABLE (-2LL) + + +/*===========================================================================*/ +/* Dwarf consumer interface initialization and termination operations */ + +/* non-elf initialization */ +int dwarf_init(int /*fd*/, + Dwarf_Unsigned /*access*/, + Dwarf_Handler /*errhand*/, + Dwarf_Ptr /*errarg*/, + Dwarf_Debug * /*dbg*/, + Dwarf_Error* /*error*/); + +/* elf intialization */ +int dwarf_elf_init(dwarf_elf_handle /*elf*/, + Dwarf_Unsigned /*access*/, + Dwarf_Handler /*errhand*/, + Dwarf_Ptr /*errarg*/, + Dwarf_Debug * /*dbg*/, + Dwarf_Error* /*error*/); + +/* Undocumented function for memory allocator. */ +void dwarf_print_memory_stats(Dwarf_Debug /*dbg*/); + + +int dwarf_get_elf(Dwarf_Debug /*dbg*/, + dwarf_elf_handle* /*return_elfptr*/, + Dwarf_Error* /*error*/); + +int dwarf_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); + +/* die traversal operations */ +int dwarf_next_cu_header(Dwarf_Debug /*dbg*/, + Dwarf_Unsigned* /*cu_header_length*/, + Dwarf_Half* /*version_stamp*/, + Dwarf_Off* /*abbrev_offset*/, + Dwarf_Half* /*address_size*/, + Dwarf_Unsigned* /*next_cu_header_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_siblingof(Dwarf_Debug /*dbg*/, + Dwarf_Die /*die*/, + Dwarf_Die* /*return_siblingdie*/, + Dwarf_Error* /*error*/); + +int dwarf_child(Dwarf_Die /*die*/, + Dwarf_Die* /*return_childdie*/, + Dwarf_Error* /*error*/); + +/* finding die given offset */ +int dwarf_offdie(Dwarf_Debug /*dbg*/, + Dwarf_Off /*offset*/, + Dwarf_Die* /*return_die*/, + Dwarf_Error* /*error*/); + +/* higher level functions (Unimplemented) */ +int dwarf_pcfile(Dwarf_Debug /*dbg*/, + Dwarf_Addr /*pc*/, + Dwarf_Die* /*return_die*/, + Dwarf_Error* /*error*/); + +/* Unimplemented */ +int dwarf_pcsubr(Dwarf_Debug /*dbg*/, + Dwarf_Addr /*pc*/, + Dwarf_Die* /*return_die*/, + Dwarf_Error* /*error*/); + +/* Unimplemented */ +int dwarf_pcscope(Dwarf_Debug /*dbg*/, + Dwarf_Addr /*pc*/, + Dwarf_Die* /*return_die*/, + Dwarf_Error* /*error*/); + +/* operations on DIEs */ +int dwarf_tag(Dwarf_Die /*die*/, + Dwarf_Half* /*return_tag*/, + Dwarf_Error* /*error*/); + +/* utility? */ +int dwarf_dieoffset(Dwarf_Die /*die*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_die_CU_offset(Dwarf_Die /*die*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_attr (Dwarf_Die /*die*/, + Dwarf_Half /*attr*/, + Dwarf_Attribute * /*returned_attr*/, + Dwarf_Error* /*error*/); + +int dwarf_diename(Dwarf_Die /*die*/, + char ** /*diename*/, + Dwarf_Error* /*error*/); + +/* convenience functions, alternative to using dwarf_attrlist() */ +int dwarf_hasattr(Dwarf_Die /*die*/, + Dwarf_Half /*attr*/, + Dwarf_Bool * /*returned_bool*/, + Dwarf_Error* /*error*/); + +/* dwarf_loclist_n preferred over dwarf_loclist */ +int dwarf_loclist_n(Dwarf_Attribute /*attr*/, + Dwarf_Locdesc*** /*llbuf*/, + Dwarf_Signed * /*locCount*/, + Dwarf_Error* /*error*/); + +int dwarf_loclist(Dwarf_Attribute /*attr*/, /* inflexible! */ + Dwarf_Locdesc** /*llbuf*/, + Dwarf_Signed * /*locCount*/, + Dwarf_Error* /*error*/); + +/* Extracts a dwarf expression from an expression byte stream. + Useful to get expressions from DW_CFA_def_cfa_expression + DW_CFA_expression DW_CFA_val_expression expression bytes. +*/ +int +dwarf_loclist_from_expr(Dwarf_Debug dbg, + Dwarf_Ptr expression_in, + Dwarf_Unsigned expression_length, + Dwarf_Locdesc ** llbuf, + Dwarf_Signed * listlen, Dwarf_Error * error); + +/* Unimplemented */ +int dwarf_stringlen(Dwarf_Die /*die*/, + Dwarf_Locdesc ** /*returned_locdesc*/, + Dwarf_Error* /*error*/); + +/* Unimplemented */ +int dwarf_subscrcnt(Dwarf_Die /*die*/, + Dwarf_Signed * /*returned_count*/, + Dwarf_Error* /*error*/); + +/* Unimplemented */ +int dwarf_nthsubscr(Dwarf_Die /*die*/, + Dwarf_Unsigned /*ssndx*/, + Dwarf_Die * /*returned_die*/, + Dwarf_Error* /*error*/); + +int dwarf_lowpc(Dwarf_Die /*die*/, + Dwarf_Addr * /*returned_addr*/, + Dwarf_Error* /*error*/); + +int dwarf_highpc(Dwarf_Die /*die*/, + Dwarf_Addr * /*returned_addr*/, + Dwarf_Error* /*error*/); + +int dwarf_bytesize(Dwarf_Die /*die*/, + Dwarf_Unsigned * /*returned_size*/, + Dwarf_Error* /*error*/); + +/* Unimplemented */ +int dwarf_isbitfield(Dwarf_Die /*die*/, + Dwarf_Bool * /*returned_bool*/, + Dwarf_Error* /*error*/); + +int dwarf_bitsize(Dwarf_Die /*die*/, + Dwarf_Unsigned * /*returned_size*/, + Dwarf_Error* /*error*/); + +int dwarf_bitoffset(Dwarf_Die /*die*/, + Dwarf_Unsigned * /*returned_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_srclang(Dwarf_Die /*die*/, + Dwarf_Unsigned * /*returned_lang*/, + Dwarf_Error* /*error*/); + +int dwarf_arrayorder(Dwarf_Die /*die*/, + Dwarf_Unsigned * /*returned_order*/, + Dwarf_Error* /*error*/); + +/* end of convenience function list */ + +/* this is the main interface to attributes of a DIE */ +int dwarf_attrlist(Dwarf_Die /*die*/, + Dwarf_Attribute** /*attrbuf*/, + Dwarf_Signed * /*attrcount*/, + Dwarf_Error* /*error*/); + +/* query operations for attributes */ +int dwarf_hasform(Dwarf_Attribute /*attr*/, + Dwarf_Half /*form*/, + Dwarf_Bool * /*returned_bool*/, + Dwarf_Error* /*error*/); + +int dwarf_whatform(Dwarf_Attribute /*attr*/, + Dwarf_Half * /*returned_form*/, + Dwarf_Error* /*error*/); + +int dwarf_whatform_direct(Dwarf_Attribute /*attr*/, + Dwarf_Half * /*returned_form*/, + Dwarf_Error* /*error*/); + +int dwarf_whatattr(Dwarf_Attribute /*attr*/, + Dwarf_Half * /*returned_attr_num*/, + Dwarf_Error* /*error*/); + +/* + The following are concerned with the Primary Interface: getting + the actual data values. One function per 'kind' of FORM. +*/ + /*dwarf_formref returns, thru return_offset, a CU-relative offset + ** and does not allow DW_FORM_ref_addr*/ +int dwarf_formref(Dwarf_Attribute /*attr*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + /*dwarf_global_formref returns, thru return_offset, + a debug_info-relative offset and does allow all reference forms*/ +int dwarf_global_formref(Dwarf_Attribute /*attr*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_formaddr(Dwarf_Attribute /*attr*/, + Dwarf_Addr * /*returned_addr*/, + Dwarf_Error* /*error*/); + +int dwarf_formflag(Dwarf_Attribute /*attr*/, + Dwarf_Bool * /*returned_bool*/, + Dwarf_Error* /*error*/); + +int dwarf_formudata(Dwarf_Attribute /*attr*/, + Dwarf_Unsigned * /*returned_val*/, + Dwarf_Error* /*error*/); + +int dwarf_formsdata(Dwarf_Attribute /*attr*/, + Dwarf_Signed * /*returned_val*/, + Dwarf_Error* /*error*/); + +int dwarf_formblock(Dwarf_Attribute /*attr*/, + Dwarf_Block ** /*returned_block*/, + Dwarf_Error* /*error*/); + +int dwarf_formstring(Dwarf_Attribute /*attr*/, + char ** /*returned_string*/, + Dwarf_Error* /*error*/); + +/* end attribute query operations. */ + +/* line number operations */ +/* dwarf_srclines is the normal interface */ +int dwarf_srclines(Dwarf_Die /*die*/, + Dwarf_Line** /*linebuf*/, + Dwarf_Signed * /*linecount*/, + Dwarf_Error* /*error*/); + +/* dwarf_srclines_dealloc, created July 2005, is the new + method for deallocating what dwarf_srclines returns. + More complete free than using dwarf_dealloc directly. */ +void dwarf_srclines_dealloc(Dwarf_Debug /*dbg*/, + Dwarf_Line* /*linebuf*/, + Dwarf_Signed /*count */); + + +int dwarf_srcfiles(Dwarf_Die /*die*/, + char*** /*srcfiles*/, + Dwarf_Signed * /*filecount*/, + Dwarf_Error* /*error*/); + +/* Unimplemented. */ +int dwarf_dieline(Dwarf_Die /*die*/, + Dwarf_Line * /*returned_line*/, + Dwarf_Error * /*error*/); + +int dwarf_linebeginstatement(Dwarf_Line /*line*/, + Dwarf_Bool * /*returned_bool*/, + Dwarf_Error* /*error*/); + +int dwarf_lineendsequence(Dwarf_Line /*line*/, + Dwarf_Bool * /*returned_bool*/, + Dwarf_Error* /*error*/); + +int dwarf_lineno(Dwarf_Line /*line*/, + Dwarf_Unsigned * /*returned_lineno*/, + Dwarf_Error* /*error*/); + +int dwarf_line_srcfileno(Dwarf_Line /*line*/, + Dwarf_Unsigned * /*ret_fileno*/, + Dwarf_Error * /*error*/); + +int dwarf_lineaddr(Dwarf_Line /*line*/, + Dwarf_Addr * /*returned_addr*/, + Dwarf_Error* /*error*/); + +int dwarf_lineoff(Dwarf_Line /*line*/, + Dwarf_Signed * /*returned_lineoffset*/, + Dwarf_Error* /*error*/); + +int dwarf_linesrc(Dwarf_Line /*line*/, + char ** /*returned_name*/, + Dwarf_Error* /*error*/); + +int dwarf_lineblock(Dwarf_Line /*line*/, + Dwarf_Bool * /*returned_bool*/, + Dwarf_Error* /*error*/); + +/* tertiary interface to line info */ +/* Unimplemented */ +int dwarf_pclines(Dwarf_Debug /*dbg*/, + Dwarf_Addr /*pc*/, + Dwarf_Line** /*linebuf*/, + Dwarf_Signed * /*linecount*/, + Dwarf_Signed /*slide*/, + Dwarf_Error* /*error*/); +/* end line number operations */ + +/* global name space operations (.debug_pubnames access) */ +int dwarf_get_globals(Dwarf_Debug /*dbg*/, + Dwarf_Global** /*globals*/, + Dwarf_Signed * /*number_of_globals*/, + Dwarf_Error* /*error*/); +void dwarf_globals_dealloc(Dwarf_Debug /*dbg*/, + Dwarf_Global* /*globals*/, + Dwarf_Signed /*number_of_globals*/); + +int dwarf_globname(Dwarf_Global /*glob*/, + char ** /*returned_name*/, + Dwarf_Error* /*error*/); + +int dwarf_global_die_offset(Dwarf_Global /*global*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error * /*error*/); + +int dwarf_get_cu_die_offset_given_cu_header_offset( + Dwarf_Debug /*dbg*/, + Dwarf_Off /*in_cu_header_offset*/, + Dwarf_Off * /*out_cu_die_offset*/, + Dwarf_Error * /*err*/); +#ifdef __sgi /* pragma is sgi MIPS only */ +#pragma optional dwarf_get_cu_die_offset_given_cu_header_offset +#endif + +int dwarf_global_cu_offset(Dwarf_Global /*global*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_global_name_offsets(Dwarf_Global /*global*/, + char ** /*returned_name*/, + Dwarf_Off* /*die_offset*/, + Dwarf_Off* /*cu_offset*/, + Dwarf_Error* /*error*/); + +/* Static function name operations. */ +int dwarf_get_funcs(Dwarf_Debug /*dbg*/, + Dwarf_Func** /*funcs*/, + Dwarf_Signed * /*number_of_funcs*/, + Dwarf_Error* /*error*/); +void dwarf_funcs_dealloc(Dwarf_Debug /*dbg*/, + Dwarf_Func* /*funcs*/, + Dwarf_Signed /*number_of_funcs*/); + +int dwarf_funcname(Dwarf_Func /*func*/, + char ** /*returned_name*/, + Dwarf_Error* /*error*/); + +int dwarf_func_die_offset(Dwarf_Func /*func*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_func_cu_offset(Dwarf_Func /*func*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_func_name_offsets(Dwarf_Func /*func*/, + char ** /*returned_name*/, + Dwarf_Off* /*die_offset*/, + Dwarf_Off* /*cu_offset*/, + Dwarf_Error* /*error*/); + +/* User-defined type name operations, SGI IRIX .debug_typenames section. + Same content as DWARF3 .debug_pubtypes, but defined years before + .debug_pubtypes was defined. SGI IRIX only. */ +int dwarf_get_types(Dwarf_Debug /*dbg*/, + Dwarf_Type** /*types*/, + Dwarf_Signed * /*number_of_types*/, + Dwarf_Error* /*error*/); +void dwarf_types_dealloc(Dwarf_Debug /*dbg*/, + Dwarf_Type* /*types*/, + Dwarf_Signed /*number_of_types*/); + + +int dwarf_typename(Dwarf_Type /*type*/, + char ** /*returned_name*/, + Dwarf_Error* /*error*/); + +int dwarf_type_die_offset(Dwarf_Type /*type*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_type_cu_offset(Dwarf_Type /*type*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_type_name_offsets(Dwarf_Type /*type*/, + char ** /*returned_name*/, + Dwarf_Off* /*die_offset*/, + Dwarf_Off* /*cu_offset*/, + Dwarf_Error* /*error*/); + +/* User-defined type name operations, DWARF3 .debug_pubtypes section. +*/ +int dwarf_get_pubtypes(Dwarf_Debug /*dbg*/, + Dwarf_Type** /*types*/, + Dwarf_Signed * /*number_of_types*/, + Dwarf_Error* /*error*/); +void dwarf_pubtypes_dealloc(Dwarf_Debug /*dbg*/, + Dwarf_Type* /*pubtypes*/, + Dwarf_Signed /*number_of_pubtypes*/); + + +int dwarf_pubtypename(Dwarf_Type /*type*/, + char ** /*returned_name*/, + Dwarf_Error* /*error*/); + +int dwarf_pubtype_die_offset(Dwarf_Type /*type*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_pubtype_cu_offset(Dwarf_Type /*type*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_pubtype_name_offsets(Dwarf_Type /*type*/, + char ** /*returned_name*/, + Dwarf_Off* /*die_offset*/, + Dwarf_Off* /*cu_offset*/, + Dwarf_Error* /*error*/); + +/* File-scope static variable name operations. */ +int dwarf_get_vars(Dwarf_Debug /*dbg*/, + Dwarf_Var** /*vars*/, + Dwarf_Signed * /*number_of_vars*/, + Dwarf_Error* /*error*/); +void dwarf_vars_dealloc(Dwarf_Debug /*dbg*/, + Dwarf_Var* /*vars*/, + Dwarf_Signed /*number_of_vars*/); + + +int dwarf_varname(Dwarf_Var /*var*/, + char ** /*returned_name*/, + Dwarf_Error* /*error*/); + +int dwarf_var_die_offset(Dwarf_Var /*var*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_var_cu_offset(Dwarf_Var /*var*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_var_name_offsets(Dwarf_Var /*var*/, + char ** /*returned_name*/, + Dwarf_Off* /*die_offset*/, + Dwarf_Off* /*cu_offset*/, + Dwarf_Error* /*error*/); + +/* weak name operations. */ +int dwarf_get_weaks(Dwarf_Debug /*dbg*/, + Dwarf_Weak** /*weaks*/, + Dwarf_Signed * /*number_of_weaks*/, + Dwarf_Error* /*error*/); +void dwarf_weaks_dealloc(Dwarf_Debug /*dbg*/, + Dwarf_Weak* /*weaks*/, + Dwarf_Signed /*number_of_weaks*/); + + +int dwarf_weakname(Dwarf_Weak /*weak*/, + char ** /*returned_name*/, + Dwarf_Error* /*error*/); + +int dwarf_weak_die_offset(Dwarf_Weak /*weak*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_weak_cu_offset(Dwarf_Weak /*weak*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_weak_name_offsets(Dwarf_Weak /*weak*/, + char ** /*returned_name*/, + Dwarf_Off* /*die_offset*/, + Dwarf_Off* /*cu_offset*/, + Dwarf_Error* /*error*/); + +/* location list section operation. (.debug_loc access) */ +int dwarf_get_loclist_entry(Dwarf_Debug /*dbg*/, + Dwarf_Unsigned /*offset*/, + Dwarf_Addr* /*hipc*/, + Dwarf_Addr* /*lopc*/, + Dwarf_Ptr* /*data*/, + Dwarf_Unsigned* /*entry_len*/, + Dwarf_Unsigned* /*next_entry*/, + Dwarf_Error* /*error*/); + +/* abbreviation section operations */ +int dwarf_get_abbrev(Dwarf_Debug /*dbg*/, + Dwarf_Unsigned /*offset*/, + Dwarf_Abbrev * /*returned_abbrev*/, + Dwarf_Unsigned* /*length*/, + Dwarf_Unsigned* /*attr_count*/, + Dwarf_Error* /*error*/); + +int dwarf_get_abbrev_tag(Dwarf_Abbrev /*abbrev*/, + Dwarf_Half* /*return_tag_number*/, + Dwarf_Error* /*error*/); +int dwarf_get_abbrev_code(Dwarf_Abbrev /*abbrev*/, + Dwarf_Unsigned* /*return_code_number*/, + Dwarf_Error* /*error*/); + +int dwarf_get_abbrev_children_flag(Dwarf_Abbrev /*abbrev*/, + Dwarf_Signed* /*return_flag*/, + Dwarf_Error* /*error*/); + +int dwarf_get_abbrev_entry(Dwarf_Abbrev /*abbrev*/, + Dwarf_Signed /*index*/, + Dwarf_Half * /*returned_attr_num*/, + Dwarf_Signed* /*form*/, + Dwarf_Off* /*offset*/, + Dwarf_Error* /*error*/); + +/* consumer string section operation */ +int dwarf_get_str(Dwarf_Debug /*dbg*/, + Dwarf_Off /*offset*/, + char** /*string*/, + Dwarf_Signed * /*strlen_of_string*/, + Dwarf_Error* /*error*/); + +/* Consumer op on gnu .eh_frame info */ +int dwarf_get_fde_list_eh( + Dwarf_Debug /*dbg*/, + Dwarf_Cie ** /*cie_data*/, + Dwarf_Signed * /*cie_element_count*/, + Dwarf_Fde ** /*fde_data*/, + Dwarf_Signed * /*fde_element_count*/, + Dwarf_Error * /*error*/); + + +/* consumer operations on frame info: .debug_frame */ +int dwarf_get_fde_list(Dwarf_Debug /*dbg*/, + Dwarf_Cie** /*cie_data*/, + Dwarf_Signed* /*cie_element_count*/, + Dwarf_Fde** /*fde_data*/, + Dwarf_Signed* /*fde_element_count*/, + Dwarf_Error* /*error*/); + +/* Release storage gotten by dwarf_get_fde_list_eh() or + dwarf_get_fde_list() */ +void dwarf_fde_cie_list_dealloc(Dwarf_Debug dbg, + Dwarf_Cie *cie_data, + Dwarf_Signed cie_element_count, + Dwarf_Fde *fde_data, + Dwarf_Signed fde_element_count); + + + +int dwarf_get_fde_range(Dwarf_Fde /*fde*/, + Dwarf_Addr* /*low_pc*/, + Dwarf_Unsigned* /*func_length*/, + Dwarf_Ptr* /*fde_bytes*/, + Dwarf_Unsigned* /*fde_byte_length*/, + Dwarf_Off* /*cie_offset*/, + Dwarf_Signed* /*cie_index*/, + Dwarf_Off* /*fde_offset*/, + Dwarf_Error* /*error*/); + +/* Useful for IRIX only: see dwarf_get_cie_augmentation_data() + dwarf_get_fde_augmentation_data() for GNU .eh_frame. */ +int dwarf_get_fde_exception_info(Dwarf_Fde /*fde*/, + Dwarf_Signed* /* offset_into_exception_tables */, + Dwarf_Error* /*error*/); + + +int dwarf_get_cie_of_fde(Dwarf_Fde /*fde*/, + Dwarf_Cie * /*cie_returned*/, + Dwarf_Error* /*error*/); + +int dwarf_get_cie_info(Dwarf_Cie /*cie*/, + Dwarf_Unsigned * /*bytes_in_cie*/, + Dwarf_Small* /*version*/, + char ** /*augmenter*/, + Dwarf_Unsigned* /*code_alignment_factor*/, + Dwarf_Signed* /*data_alignment_factor*/, + Dwarf_Half* /*return_address_register_rule*/, + Dwarf_Ptr* /*initial_instructions*/, + Dwarf_Unsigned* /*initial_instructions_length*/, + Dwarf_Error* /*error*/); + +int dwarf_get_fde_instr_bytes(Dwarf_Fde /*fde*/, + Dwarf_Ptr * /*outinstrs*/, Dwarf_Unsigned * /*outlen*/, + Dwarf_Error * /*error*/); + +int dwarf_get_fde_info_for_all_regs(Dwarf_Fde /*fde*/, + Dwarf_Addr /*pc_requested*/, + Dwarf_Regtable* /*reg_table*/, + Dwarf_Addr* /*row_pc*/, + Dwarf_Error* /*error*/); + +int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde /*fde*/, + Dwarf_Addr /*pc_requested*/, + Dwarf_Regtable3* /*reg_table*/, + Dwarf_Addr* /*row_pc*/, + Dwarf_Error* /*error*/); + +/* In this older interface DW_FRAME_CFA_COL is a meaningful + column (which does not work well with DWARF3 or + non-MIPS architectures). */ +int dwarf_get_fde_info_for_reg(Dwarf_Fde /*fde*/, + Dwarf_Half /*table_column*/, + Dwarf_Addr /*pc_requested*/, + Dwarf_Signed* /*offset_relevant*/, + Dwarf_Signed* /*register*/, + Dwarf_Signed* /*offset*/, + Dwarf_Addr* /*row_pc*/, + Dwarf_Error* /*error*/); + +/* See discussion of dw_value_type, libdwarf.h. + Use of DW_FRAME_CFA_COL is not meaningful in this interface. + Nor is DDW_FRAME_CFA_COL3. + See dwarf_get_fde_info_for_cfa_reg3(). +*/ +int dwarf_get_fde_info_for_reg3(Dwarf_Fde /*fde*/, + Dwarf_Half /*table_column*/, + Dwarf_Addr /*pc_requested*/, + Dwarf_Small * /*value_type*/, + Dwarf_Signed * /*offset_relevant*/, + Dwarf_Signed* /*register*/, + Dwarf_Signed* /*offset_or_block_len*/, + Dwarf_Ptr * /*block_ptr */, + Dwarf_Addr* /*row_pc_out*/, + Dwarf_Error* /*error*/); + +/* Use this to get the cfa. */ +int dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde /*fde*/, + Dwarf_Addr /*pc_requested*/, + Dwarf_Small * /*value_type*/, + Dwarf_Signed * /*offset_relevant*/, + Dwarf_Signed* /*register*/, + Dwarf_Signed* /*offset_or_block_len*/, + Dwarf_Ptr * /*block_ptr */, + Dwarf_Addr* /*row_pc_out*/, + Dwarf_Error* /*error*/); + +int dwarf_get_fde_for_die(Dwarf_Debug /*dbg*/, + Dwarf_Die /*subr_die */, + Dwarf_Fde * /*returned_fde*/, + Dwarf_Error* /*error*/); + +int dwarf_get_fde_n(Dwarf_Fde* /*fde_data*/, + Dwarf_Unsigned /*fde_index*/, + Dwarf_Fde * /*returned_fde*/, + Dwarf_Error* /*error*/); + +int dwarf_get_fde_at_pc(Dwarf_Fde* /*fde_data*/, + Dwarf_Addr /*pc_of_interest*/, + Dwarf_Fde * /*returned_fde*/, + Dwarf_Addr* /*lopc*/, + Dwarf_Addr* /*hipc*/, + Dwarf_Error* /*error*/); + +/* GNU .eh_frame augmentation information, raw form, see + Linux Standard Base Core Specification version 3.0 . */ +int dwarf_get_cie_augmentation_data(Dwarf_Cie /* cie*/, + Dwarf_Small ** /* augdata */, + Dwarf_Unsigned * /* augdata_len */, + Dwarf_Error* /*error*/); +/* GNU .eh_frame augmentation information, raw form, see + Linux Standard Base Core Specification version 3.0 . */ +int dwarf_get_fde_augmentation_data(Dwarf_Fde /* fde*/, + Dwarf_Small ** /* augdata */, + Dwarf_Unsigned * /* augdata_len */, + Dwarf_Error* /*error*/); + +int dwarf_expand_frame_instructions(Dwarf_Debug /*dbg*/, + Dwarf_Ptr /*instruction*/, + Dwarf_Unsigned /*i_length*/, + Dwarf_Frame_Op** /*returned_op_list*/, + Dwarf_Signed* /*op_count*/, + Dwarf_Error* /*error*/); + +/* Operations on .debug_aranges. */ +int dwarf_get_aranges(Dwarf_Debug /*dbg*/, + Dwarf_Arange** /*aranges*/, + Dwarf_Signed * /*arange_count*/, + Dwarf_Error* /*error*/); + + + +int dwarf_get_arange( + Dwarf_Arange* /*aranges*/, + Dwarf_Unsigned /*arange_count*/, + Dwarf_Addr /*address*/, + Dwarf_Arange * /*returned_arange*/, + Dwarf_Error* /*error*/); + +int dwarf_get_cu_die_offset( + Dwarf_Arange /*arange*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_get_arange_cu_header_offset( + Dwarf_Arange /*arange*/, + Dwarf_Off* /*return_cu_header_offset*/, + Dwarf_Error* /*error*/); +#ifdef __sgi /* pragma is sgi MIPS only */ +#pragma optional dwarf_get_arange_cu_header_offset +#endif + +int dwarf_get_arange_info( + Dwarf_Arange /*arange*/, + Dwarf_Addr* /*start*/, + Dwarf_Unsigned* /*length*/, + Dwarf_Off* /*cu_die_offset*/, + Dwarf_Error* /*error*/); + + +/* consumer .debug_macinfo information interface. +*/ +struct Dwarf_Macro_Details_s { + Dwarf_Off dmd_offset; /* offset, in the section, + of this macro info */ + Dwarf_Small dmd_type; /* the type, DW_MACINFO_define etc*/ + Dwarf_Signed dmd_lineno; /* the source line number where + applicable and vend_def # if + vendor_extension op + */ + + Dwarf_Signed dmd_fileindex;/* the source file index: + applies to define undef start_file + */ + char * dmd_macro; /* macro name (with value for defineop) + string from vendor ext + */ +}; + +/* dwarf_print_lines is for use by dwarfdump: it prints + line info to stdout. + The _dwarf name is obsolete. Use dwarf_ instead. +*/ +int _dwarf_print_lines(Dwarf_Die cu_die,Dwarf_Error * /*error*/); +int dwarf_print_lines(Dwarf_Die cu_die,Dwarf_Error * /*error*/); + +/* dwarf_ld_sort_lines helps SGI IRIX ld + rearrange lines in .debug_line in a .o created with a text + section per function. + -OPT:procedure_reorder=ON + where ld-cord (cord(1)ing by ld, + not by cord(1)) may have changed the function order. + The _dwarf name is obsolete. Use dwarf_ instead. +*/ +int _dwarf_ld_sort_lines( + void * orig_buffer, + unsigned long buffer_len, + int is_64_bit, + int *any_change, + int * err_code); +int dwarf_ld_sort_lines( + void * orig_buffer, + unsigned long buffer_len, + int is_64_bit, + int *any_change, + int * err_code); + +/* Used by dwarfdump -v to print fde offsets from debugging + info. + The _dwarf name is obsolete. Use dwarf_ instead. +*/ +int _dwarf_fde_section_offset(Dwarf_Debug dbg,Dwarf_Fde in_fde, + Dwarf_Off *fde_off, Dwarf_Off *cie_off, + Dwarf_Error *err); +int dwarf_fde_section_offset(Dwarf_Debug dbg,Dwarf_Fde in_fde, + Dwarf_Off *fde_off, Dwarf_Off *cie_off, + Dwarf_Error *err); + +/* Used by dwarfdump -v to print cie offsets from debugging + info. + The _dwarf name is obsolete. Use dwarf_ instead. +*/ +int dwarf_cie_section_offset(Dwarf_Debug dbg,Dwarf_Cie in_cie, + Dwarf_Off *cie_off, + Dwarf_Error *err); +int _dwarf_cie_section_offset(Dwarf_Debug dbg,Dwarf_Cie in_cie, + Dwarf_Off *cie_off, + Dwarf_Error *err); + + + + +typedef struct Dwarf_Macro_Details_s Dwarf_Macro_Details; + +int dwarf_get_macro(Dwarf_Debug /*dbg*/, + char * /*requested_macro_name*/, + Dwarf_Addr /*pc_of_request*/, + char ** /*returned_macro_value*/, + Dwarf_Error * /*error*/); + +int dwarf_get_all_defined_macros(Dwarf_Debug /*dbg*/, + Dwarf_Addr /*pc_of_request*/, + Dwarf_Signed * /*returned_count*/, + char *** /*returned_pointers_to_macros*/, + Dwarf_Error * /*error*/); + +char *dwarf_find_macro_value_start(char * /*macro_string*/); + +int dwarf_get_macro_details(Dwarf_Debug /*dbg*/, + Dwarf_Off /*macro_offset*/, + Dwarf_Unsigned /*maximum_count*/, + Dwarf_Signed * /*entry_count*/, + Dwarf_Macro_Details ** /*details*/, + Dwarf_Error * /*err*/); + + +int dwarf_get_address_size(Dwarf_Debug /*dbg*/, + Dwarf_Half * /*addr_size*/, + Dwarf_Error * /*error*/); + +/* utility operations */ +Dwarf_Unsigned dwarf_errno(Dwarf_Error /*error*/); + +char* dwarf_errmsg(Dwarf_Error /*error*/); + +/* stringcheck zero is default and means do all +** string length validity checks. +** Call with parameter value 1 to turn off many such checks (and +** increase performance). +** Call with zero for safest running. +** Actual value saved and returned is only 8 bits! Upper bits +** ignored by libdwarf (and zero on return). +** Returns previous value. +*/ +int dwarf_set_stringcheck(int /*stringcheck*/); + +/* Unimplemented */ +Dwarf_Handler dwarf_seterrhand(Dwarf_Debug /*dbg*/, Dwarf_Handler /*errhand*/); + +/* Unimplemented */ +Dwarf_Ptr dwarf_seterrarg(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*errarg*/); + +void dwarf_dealloc(Dwarf_Debug /*dbg*/, void* /*space*/, + Dwarf_Unsigned /*type*/); + +/* DWARF Producer Interface */ + +typedef int (*Dwarf_Callback_Func)( + char* /*name*/, + int /*size*/, + Dwarf_Unsigned /*type*/, + Dwarf_Unsigned /*flags*/, + Dwarf_Unsigned /*link*/, + Dwarf_Unsigned /*info*/, + int* /*sect name index*/, + int* /*error*/); + +Dwarf_P_Debug dwarf_producer_init( + Dwarf_Unsigned /*creation_flags*/, + Dwarf_Callback_Func /*func*/, + Dwarf_Handler /*errhand*/, + Dwarf_Ptr /*errarg*/, + Dwarf_Error* /*error*/); + +typedef int (*Dwarf_Callback_Func_b)( + char* /*name*/, + int /*size*/, + Dwarf_Unsigned /*type*/, + Dwarf_Unsigned /*flags*/, + Dwarf_Unsigned /*link*/, + Dwarf_Unsigned /*info*/, + Dwarf_Unsigned* /*sect_name_index*/, + int* /*error*/); + + +Dwarf_P_Debug dwarf_producer_init_b( + Dwarf_Unsigned /*flags*/, + Dwarf_Callback_Func_b /*func*/, + Dwarf_Handler /*errhand*/, + Dwarf_Ptr /*errarg*/, + Dwarf_Error * /*error*/); + + +Dwarf_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug /*dbg*/, + Dwarf_Error* /*error*/); + +Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug /*dbg*/, + Dwarf_Signed /*dwarf_section*/, + Dwarf_Signed* /*elf_section_index*/, + Dwarf_Unsigned* /*length*/, + Dwarf_Error* /*error*/); + +int dwarf_get_relocation_info_count( + Dwarf_P_Debug /*dbg*/, + Dwarf_Unsigned * /*count_of_relocation_sections*/, + int * /*drd_buffer_version*/, + Dwarf_Error* /*error*/); + +int dwarf_get_relocation_info( + Dwarf_P_Debug /*dbg*/, + Dwarf_Signed * /*elf_section_index*/, + Dwarf_Signed * /*elf_section_index_link*/, + Dwarf_Unsigned * /*relocation_buffer_count*/, + Dwarf_Relocation_Data * /*reldata_buffer*/, + Dwarf_Error* /*error*/); + +/* v1: no drd_length field, enum explicit */ +/* v2: has the drd_length field, enum value in uchar member */ +#define DWARF_DRD_BUFFER_VERSION 2 + +Dwarf_Signed dwarf_get_die_markers( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Marker * /*marker_list*/, + Dwarf_Unsigned * /*marker_count*/, + Dwarf_Error * /*error*/); + +int dwarf_get_string_attributes_count(Dwarf_P_Debug, + Dwarf_Unsigned *, + int *, + Dwarf_Error *); + +int dwarf_get_string_attributes_info(Dwarf_P_Debug, + Dwarf_Signed *, + Dwarf_Unsigned *, + Dwarf_P_String_Attr *, + Dwarf_Error *); + +void dwarf_reset_section_bytes(Dwarf_P_Debug /*dbg*/); + +Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug /*dbg*/, + Dwarf_Error* /*error*/); + +/* Producer attribute addition functions. */ +Dwarf_P_Attribute dwarf_add_AT_targ_address(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_Unsigned /*pc_value*/, + Dwarf_Signed /*sym_index*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_block(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_Small* /*block_data*/, + Dwarf_Unsigned /*block_len*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_Unsigned /*pc_value*/, + Dwarf_Unsigned /*sym_index*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_ref_address(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_Unsigned /*pc_value*/, + Dwarf_Unsigned /*sym_index*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_unsigned_const(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_Unsigned /*value*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_signed_const(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_Signed /*value*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_P_Die /*otherdie*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_dataref( + Dwarf_P_Debug /* dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_Unsigned /*pcvalue*/, + Dwarf_Unsigned /*sym_index*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_const_value_string(Dwarf_P_Die /*ownerdie*/, + char* /*string_value*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_P_Expr /*loc_expr*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_string(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + char* /*string*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_flag(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_Small /*flag*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_producer(Dwarf_P_Die /*ownerdie*/, + char* /*producer_string*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_const_value_signedint(Dwarf_P_Die /*ownerdie*/, + Dwarf_Signed /*signed_value*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_const_value_unsignedint( + Dwarf_P_Die /*ownerdie*/, + Dwarf_Unsigned /*unsigned_value*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_comp_dir(Dwarf_P_Die /*ownerdie*/, + char* /*current_working_directory*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die /*die*/, + char* /*name*/, + Dwarf_Error* /*error*/); + +/* Producer line creation functions (.debug_line) */ +Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug /*dbg*/, + char* /*name*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug /*dbg*/, + char* /*name*/, + Dwarf_Unsigned /*dir_index*/, + Dwarf_Unsigned /*time_last_modified*/, + Dwarf_Unsigned /*length*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_line_entry(Dwarf_P_Debug /*dbg*/, + Dwarf_Unsigned /*file_index*/, + Dwarf_Addr /*code_address*/, + Dwarf_Unsigned /*lineno*/, + Dwarf_Signed /*column_number*/, + Dwarf_Bool /*is_source_stmt_begin*/, + Dwarf_Bool /*is_basic_block_begin*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_lne_set_address(Dwarf_P_Debug /*dbg*/, + Dwarf_Unsigned /*offset*/, + Dwarf_Unsigned /*symbol_index*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug /*dbg*/, + Dwarf_Addr /*end_address*/, + Dwarf_Error* /*error*/); + +/* Producer .debug_frame functions */ +Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug /*dbg*/, + char* /*augmenter*/, + Dwarf_Small /*code_alignent_factor*/, + Dwarf_Small /*data_alignment_factor*/, + Dwarf_Small /*return_address_reg*/, + Dwarf_Ptr /*initialization_bytes*/, + Dwarf_Unsigned /*init_byte_len*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_frame_fde( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Fde /*fde*/, + Dwarf_P_Die /*corresponding subprogram die*/, + Dwarf_Unsigned /*cie_to_use*/, + Dwarf_Unsigned /*virt_addr_of_described_code*/, + Dwarf_Unsigned /*length_of_code*/, + Dwarf_Unsigned /*symbol_index*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_frame_fde_b( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Fde /*fde*/, + Dwarf_P_Die /*die*/, + Dwarf_Unsigned /*cie*/, + Dwarf_Addr /*virt_addr*/, + Dwarf_Unsigned /*code_len*/, + Dwarf_Unsigned /*sym_idx*/, + Dwarf_Unsigned /*sym_idx_of_end*/, + Dwarf_Addr /*offset_from_end_sym*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_frame_info_b( + Dwarf_P_Debug dbg /*dbg*/, + Dwarf_P_Fde /*fde*/, + Dwarf_P_Die /*die*/, + Dwarf_Unsigned /*cie*/, + Dwarf_Addr /*virt_addr*/, + Dwarf_Unsigned /*code_len*/, + Dwarf_Unsigned /*symidx*/, + Dwarf_Unsigned /* end_symbol */, + Dwarf_Addr /* offset_from_end_symbol */, + Dwarf_Signed /*offset_into_exception_tables*/, + Dwarf_Unsigned /*exception_table_symbol*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_frame_info( + Dwarf_P_Debug dbg /*dbg*/, + Dwarf_P_Fde /*fde*/, + Dwarf_P_Die /*die*/, + Dwarf_Unsigned /*cie*/, + Dwarf_Addr /*virt_addr*/, + Dwarf_Unsigned /*code_len*/, + Dwarf_Unsigned /*symidx*/, + Dwarf_Signed /*offset_into_exception_tables*/, + Dwarf_Unsigned /*exception_table_symbol*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Fde dwarf_add_fde_inst( + Dwarf_P_Fde /*fde*/, + Dwarf_Small /*op*/, + Dwarf_Unsigned /*val1*/, + Dwarf_Unsigned /*val2*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); + +Dwarf_P_Fde dwarf_fde_cfa_offset( + Dwarf_P_Fde /*fde*/, + Dwarf_Unsigned /*register_number*/, + Dwarf_Signed /*offset*/, + Dwarf_Error* /*error*/); + +/* die creation & addition routines */ +Dwarf_P_Die dwarf_new_die( + Dwarf_P_Debug /*dbg*/, + Dwarf_Tag /*tag*/, + Dwarf_P_Die /*parent*/, + Dwarf_P_Die /*child*/, + Dwarf_P_Die /*left */, + Dwarf_P_Die /*right*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_die_to_debug( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_die_marker( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + Dwarf_Unsigned /*marker*/, + Dwarf_Error * /*error*/); + +Dwarf_Unsigned dwarf_get_die_marker( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + Dwarf_Unsigned * /*marker*/, + Dwarf_Error * /*error*/); + +Dwarf_P_Die dwarf_die_link( + Dwarf_P_Die /*die*/, + Dwarf_P_Die /*parent*/, + Dwarf_P_Die /*child*/, + Dwarf_P_Die /*left*/, + Dwarf_P_Die /*right*/, + Dwarf_Error* /*error*/); + +void dwarf_dealloc_compressed_block( + Dwarf_P_Debug, + void * +); + +void dwarf_dealloc_uncompressed_block( + Dwarf_Debug, + void * +); + +void * dwarf_compress_integer_block( + Dwarf_P_Debug, /* dbg */ + Dwarf_Bool, /* signed==true (or unsigned) */ + Dwarf_Small, /* size of integer units: 8, 16, 32, 64 */ + void*, /* data */ + Dwarf_Unsigned, /* number of elements */ + Dwarf_Unsigned*, /* number of bytes in output block */ + Dwarf_Error* /* error */ +); + +void * dwarf_uncompress_integer_block( + Dwarf_Debug, /* dbg */ + Dwarf_Bool, /* signed==true (or unsigned) */ + Dwarf_Small, /* size of integer units: 8, 16, 32, 64 */ + void*, /* data */ + Dwarf_Unsigned, /* number of bytes in input */ + Dwarf_Unsigned*, /* number of units in output block */ + Dwarf_Error* /* error */ +); + +/* Operations to create location expressions. */ +Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); + +void dwarf_expr_reset( + Dwarf_P_Expr /*expr*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_expr_gen( + Dwarf_P_Expr /*expr*/, + Dwarf_Small /*opcode*/, + Dwarf_Unsigned /*val1*/, + Dwarf_Unsigned /*val2*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_expr_addr( + Dwarf_P_Expr /*expr*/, + Dwarf_Unsigned /*addr*/, + Dwarf_Signed /*sym_index*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_expr_addr_b( + Dwarf_P_Expr /*expr*/, + Dwarf_Unsigned /*addr*/, + Dwarf_Unsigned /*sym_index*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_expr_current_offset( + Dwarf_P_Expr /*expr*/, + Dwarf_Error* /*error*/); + +Dwarf_Addr dwarf_expr_into_block( + Dwarf_P_Expr /*expr*/, + Dwarf_Unsigned* /*length*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_arange(Dwarf_P_Debug /*dbg*/, + Dwarf_Addr /*begin_address*/, + Dwarf_Unsigned /*length*/, + Dwarf_Signed /*symbol_index*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_arange_b( + Dwarf_P_Debug /*dbg*/, + Dwarf_Addr /*begin_address*/, + Dwarf_Unsigned /*length*/, + Dwarf_Unsigned /*symbol_index*/, + Dwarf_Unsigned /*end_symbol_index*/, + Dwarf_Addr /*offset_from_end_symbol*/, + Dwarf_Error * /*error*/); + +Dwarf_Unsigned dwarf_add_pubname( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + char* /*pubname_name*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_funcname( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + char* /*func_name*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_typename( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + char* /*type_name*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_varname( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + char* /*var_name*/, + Dwarf_Error* /*error*/); + +Dwarf_Unsigned dwarf_add_weakname( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + char* /*weak_name*/, + Dwarf_Error* /*error*/); + +/* .debug_macinfo producer functions + Functions must be called in right order: the section is output + In the order these are presented. +*/ +int dwarf_def_macro(Dwarf_P_Debug /*dbg*/, + Dwarf_Unsigned /*line*/, + char * /*macname, with (arglist), no space before (*/, + char * /*macvalue*/, + Dwarf_Error* /*error*/); + +int dwarf_undef_macro(Dwarf_P_Debug /*dbg*/, + Dwarf_Unsigned /*line*/, + char * /*macname, no arglist, of course*/, + Dwarf_Error* /*error*/); + +int dwarf_start_macro_file(Dwarf_P_Debug /*dbg*/, + Dwarf_Unsigned /*fileindex*/, + Dwarf_Unsigned /*linenumber*/, + Dwarf_Error* /*error*/); + +int dwarf_end_macro_file(Dwarf_P_Debug /*dbg*/, + Dwarf_Error* /*error*/); + +int dwarf_vendor_ext(Dwarf_P_Debug /*dbg*/, + Dwarf_Unsigned /*constant*/, + char * /*string*/, + Dwarf_Error* /*error*/); + +/* end macinfo producer functions */ + +int dwarf_attr_offset(Dwarf_Die /*die*/, + Dwarf_Attribute /*attr of above die*/, + Dwarf_Off * /*returns offset thru this ptr */, + Dwarf_Error * /*error*/); + +/* This is a hack so clients can verify offsets. + Added April 2005 so that debugger can detect broken offsets + (which happened in an IRIX executable larger than 2GB + with MIPSpro 7.3.1.3 toolchain.). +*/ +int +dwarf_get_section_max_offsets(Dwarf_Debug /*dbg*/, + Dwarf_Unsigned * /*debug_info_size*/, + Dwarf_Unsigned * /*debug_abbrev_size*/, + Dwarf_Unsigned * /*debug_line_size*/, + Dwarf_Unsigned * /*debug_loc_size*/, + Dwarf_Unsigned * /*debug_aranges_size*/, + Dwarf_Unsigned * /*debug_macinfo_size*/, + Dwarf_Unsigned * /*debug_pubnames_size*/, + Dwarf_Unsigned * /*debug_str_size*/, + Dwarf_Unsigned * /*debug_frame_size*/, + Dwarf_Unsigned * /*debug_ranges_size*/, + Dwarf_Unsigned * /*debug_pubtypes_size*/); + +Dwarf_Half +dwarf_set_frame_rule_inital_value(Dwarf_Debug /*dbg*/, + Dwarf_Half /*value*/); + +Dwarf_Half +dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, + Dwarf_Half value); + + +#ifdef __cplusplus +} +#endif +#endif /* _LIBDWARF_H */ + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2.1.mm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2.1.mm Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,5215 @@ +\." +\." the following line may be removed if the ff ligature works on your machine +.lg 0 +\." set up heading formats +.ds HF 3 3 3 3 3 2 2 +.ds HP +2 +2 +1 +0 +0 +.nr Hs 5 +.nr Hb 5 +\." ============================================== +\." Put current date in the following at each rev +.ds vE rev 1.66, 04 July 2007 +\." ============================================== +\." ============================================== +.ds | | +.ds ~ ~ +.ds ' ' +.if t .ds Cw \&\f(CW +.if n .ds Cw \fB +.de Cf \" Place every other arg in Cw font, beginning with first +.if \\n(.$=1 \&\*(Cw\\$1\fP +.if \\n(.$=2 \&\*(Cw\\$1\fP\\$2 +.if \\n(.$=3 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP +.if \\n(.$=4 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4 +.if \\n(.$=5 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP +.if \\n(.$=6 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6 +.if \\n(.$=7 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP +.if \\n(.$=8 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8 +.if \\n(.$=9 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8\ +*(Cw +.. +.nr Cl 4 +.SA 1 +.TL +A Consumer Library Interface to DWARF +.AF "" +.AU "David Anderson" +.PF "'\*(vE'- \\\\nP -''" +.AS 1 +This document describes an interface to a library of functions +.FS +UNIX is a registered trademark of UNIX System Laboratories, Inc. +in the United States and other countries. +.FE +to access DWARF debugging information entries and DWARF line number +information (and other DWARF2/3 information). +It does not make recommendations as to how the functions +described in this document should be implemented nor does it +suggest possible optimizations. +.P +The document is oriented to reading DWARF version 2 +and version 3. +There are certain sections which are SGI-specific (those +are clearly identified in the document). +.P +\*(vE + +.AE +.MT 4 + +.H 1 "INTRODUCTION" +This document describes an interface to \fIlibdwarf\fP, a +library of functions to provide access to DWARF debugging information +records, DWARF line number information, DWARF address range and global +names information, weak names information, DWARF frame description +information, DWARF static function names, DWARF static variables, and +DWARF type information. +.P +The document has long mentioned the +"Unix International Programming Languages Special Interest Group" +(PLSIG), under whose auspices the +DWARF committtee was formed around 1991. +"Unix International" +was disbanded in the 1990's and no longer exists. +.P +The DWARF committee published DWARF2 July 27, 1993. +.P +In the mid 1990's this document and the library it describes +(which the committee never endorsed, having decided +not to endorse or approve any particular library interface) +was made available on the internet by Silcon Graphics, Inc. +.P +In 2005 the DWARF committee began an affiliation with FreeStandards.org. +In 2007 FreeStandards.org merged with The Linux Foundation. +The DWARF committee dropped its affiliation with FreeStandards.org +in 2007 and established the dwarfstd.org website. +See "http://www.dwarfstd.org" for current +information on standardization activities +and a copy of the standard. +.H 2 "Copyright" +Copyright 1993-2006 Silicon Graphics, Inc. + +Copyright 2007 David Anderson. + +Permission is hereby granted to +copy or republish or use any or all of this document without +restriction except that when publishing more than a small amount +of the document +please acknowledge Silicon Graphics, Inc and David Anderson. + +This document is distributed in the hope that it would be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +.P + +.H 2 "Purpose and Scope" +The purpose of this document is to document a library of functions +to access DWARF debugging information. There is no effort made in +this document to address the creation of these records as those +issues are addressed separately +(see "A Producer Library Interface to DWARF"). + +.P +Additionally, the focus of this document is the functional interface, +and as such, implementation as well as optimization issues are +intentionally ignored. + + +.H 2 "Document History" +.P +A document was written about 1991 which had similar +layout and interfaces. +Written by people from Hal Corporation, +That document described a library for reading DWARF1. +The authors distributed paper copies to the committee +with the clearly expressed intent to propose the document as +a supported interface definition. +The committee decided not to pursue a library definition. +.P +SGI wrote the document you are now reading in 1993 +with a similar layout and content and organization, but +it was complete document rewrite with the intent to read DWARF2 +(the DWARF version then in existence). +The intent was (and is) to also cover +future revisions of DWARF. +All the function interfaces were changed +in 1994 to uniformly +return a simple integer success-code (see DW_DLV_OK etc), +generally following +the recomendations in the chapter titled "Candy Machine Interfaces" +of "Writing Solid Code", a book by +Steve Maguire (published by Microsoft Press). +.H 2 "Definitions" +DWARF debugging information entries (DIEs) are the segments of information +placed in the \f(CW.debug_*\fP sections by compilers, assemblers, and +linkage editors that, in conjunction with line number entries, are +necessary for symbolic source-level debugging. +Refer to the latest +"\fIDWARF Debugging Information Format\fP" from www.dwarfstd.org for a more +complete description of these entries. + +.P +This document adopts all the terms and definitions in "\fIDWARF Debugging +Information Format\fP" versions 2 and 3. +It originally focused on the implementation at +Silicon Graphics, Inc., but now +attempts to be more generally useful. + +.H 2 "Overview" +The remaining sections of this document describe the proposed interface +to \f(CWlibdwarf\fP, first by describing the purpose of additional types +defined by the interface, followed by descriptions of the available +operations. This document assumes you are thoroughly familiar with the +information contained in the \fIDWARF Debugging Information Format\fP +document. +.P +We separate the functions into several categories to emphasize that not +all consumers want to use all the functions. We call the categories +Debugger, Internal-level, High-level, and Miscellaneous not because one is more +important than another but as a way of making the rather large set of +function calls easier to understand. +.P +Unless otherwise specified, all functions and structures should be +taken as being designed for Debugger consumers. +.P +The Debugger Interface of this library is intended to be used by debuggers. +The interface is low-level (close to dwarf) but suppresses irrelevant detail. +A debugger will want to absorb all of some sections at startup and will +want to see little or nothing of some sections except at need. And even +then will probably want to absorb only the information in a single compilation +unit at a time. A debugger does not care about +implementation details of the library. +.P +The Internal-level Interface is for a DWARF prettyprinter and checker. +A +thorough prettyprinter will want to know all kinds of internal things +(like actual FORM numbers and actual offsets) so it can check for +appropriate structure in the DWARF data and print (on request) all +that internal information for human users and libdwarf authors and +compiler-writers. +Calls in this interface provide data a debugger +does not care about. +.P +The High-level Interface is for higher level access +(it's not really a high level interface!). +Programs such as +disassemblers will want to be able to display relevant information +about functions and line numbers without having to invest too much +effort in looking at DWARF. +.P +The miscellaneous interface is just what is left over: the error handler +functions. +.P +The following is a brief mention of the changes in this libdwarf from +the libdwarf draft for DWARF Version 1 and recent changes. +.H 2 "Items Changed" +.P +Added support for various DWARF3 features, but primarily +a new frame-information interface tailorable at run-time +to more than a single ABI. +See dwarf_set_frame_rule_inital_value() and dwarf_set_frame_rule_table_size(). +See also dwarf_get_fde_info_for_reg3() and +dwarf_get_fde_info_for_cfa_reg3(). (April 2006) +.P +Added support for DWARF3 .debug_pubtypes section. +Corrected various leaks (revising dealloc() calls, adding +new functions) and corrected dwarf_formstring() documentation. +.P +Added dwarf_srclines_dealloc() as the previous deallocation +method documented for data returned by +dwarf_srclines() was incapable of freeing +all the allocated storage (14 July 2005). +.P +dwarf_nextglob(), dwarf_globname(), and dwarf_globdie() were all changed +to operate on the items in the .debug_pubnames section. +.P +All functions were modified to return solely an error code. +Data is returned through pointer arguments. +This makes writing safe and correct library-using-code far easier. +For justification for this approach, see the book by +Steve Maguire titled "Writing Solid Code" at your bookstore. + + +.H 2 "Items Removed" +.P +Dwarf_Type +was removed since types are no longer special. +.P +dwarf_typeof() +was removed since types are no longer special. +.P +Dwarf_Ellist +was removed since element lists no longer are a special format. +.P +Dwarf_Bounds +was removed since bounds have been generalized. +.P +dwarf_nextdie() +was replaced by dwarf_next_cu_header() to reflect the +real way DWARF is organized. +The dwarf_nextdie() was only useful for getting to compilation +unit beginnings, so it does not seem harmful to remove it in favor +of a more direct function. +.P +dwarf_childcnt() is removed on grounds +that no good use was apparent. +.P +dwarf_prevline() and dwarf_nextline() were removed on grounds this +is better left to a debugger to do. +Similarly, dwarf_dieline() was removed. +.P +dwarf_is1stline() was removed as it was not meaningful for the +revised DWARF line operations. +.P +Any libdwarf implementation might well decide to support all the +removed functionality and to retain the DWARF Version 1 meanings +of that functionality. +This would be difficult because the +original libdwarf draft +specification used traditional C library interfaces which +confuse the values returned by successful calls with +exceptional conditions like failures and 'no more data' indications. + +.H 2 "Revision History" +.VL 15 +.LI "March 93" +Work on DWARF2 SGI draft begins +.LI "June 94" +The function returns are changed to return an error/success code +only. +.LI "April 2006: +Support for DWARF3 consumer operations is close to completion. +.LE + +.H 1 "Types Definitions" + +.H 2 "General Description" +The \fIlibdwarf.h\fP header file contains typedefs and preprocessor +definitions of types and symbolic names used to reference objects +of \fIlibdwarf\fP. The types defined by typedefs contained in +\fIlibdwarf.h\fP all use the convention of adding \f(CWDwarf_\fP +as a prefix and can be placed in three categories: + +.BL +.LI +Scalar types : The scalar types defined in \fIlibdwarf.h\fP are +defined primarily for notational convenience and identification. +Depending on the individual definition, they are interpreted as a +value, a pointer, or as a flag. +.LI +Aggregate types : Some values can not be represented by a single +scalar type; they must be represented by a collection of, or as a +union of, scalar and/or aggregate types. +.LI +Opaque types : The complete definition of these types is intentionally +omitted; their use is as handles for query operations, which will yield +either an instance of another opaque type to be used in another query, or +an instance of a scalar or aggregate type, which is the actual result. +.P + +.H 2 "Scalar Types" +The following are the defined by \fIlibdwarf.h\fP: + +.DS +\f(CW +typedef int Dwarf_Bool; +typedef unsigned long long Dwarf_Off; +typedef unsigned long long Dwarf_Unsigned; +typedef unsigned short Dwarf_Half; +typedef unsigned char Dwarf_Small; +typedef signed long long Dwarf_Signed; +typedef unsigned long long Dwarf_Addr; +typedef void *Dwarf_Ptr; +typedef void (*Dwarf_Handler)(Dwarf_Error *error, Dwarf_Ptr errarg); +.DE + +.nr aX \n(Fg+1 +Dwarf_Ptr is an address for use by the host program calling the library, +not for representing pc-values/addresses within the target object file. +Dwarf_Addr is for pc-values within the target object file. The sample +scalar type assignments above are for a \fIlibdwarf.h\fP that can read +and write +32-bit or 64-bit binaries on a 32-bit or 64-bit host machine. +The types must be defined appropriately +for each implementation of libdwarf. +A description of these scalar types in the SGI/MIPS +environment is given in Figure \n(aX. + +.DS +.TS +center box, tab(:); +lfB lfB lfB lfB +l c c l. +NAME:SIZE:ALIGNMENT:PURPOSE +_ +Dwarf_Bool:4:4:Boolean states +Dwarf_Off:8:8:Unsigned file offset +Dwarf_Unsigned:8:8:Unsigned large integer +Dwarf_Half:2:2:Unsigned medium integer +Dwarf_Small:1:1:Unsigned small integer +Dwarf_Signed:8:8:Signed large integer +Dwarf_Addr:8:8:Program address +:::(target program) +Dwarf_Ptr:4|8:4|8:Dwarf section pointer +:::(host program) +Dwarf_Handler:4|8:4|8:Pointer to +:::error handler function +.TE +.FG "Scalar Types" +.DE + +.H 2 "Aggregate Types" +The following aggregate types are defined by +\fIlibdwarf.h\fP: +\f(CWDwarf_Loc\fP, +\f(CWDwarf_Locdesc\fP, +\f(CWDwarf_Block\fP, +\f(CWDwarf_Frame_Op\fP. +\f(CWDwarf_Regtable\fP. +\f(CWDwarf_Regtable3\fP. +While most of \f(CWlibdwarf\fP acts on or returns simple values or +opaque pointer types, this small set of structures seems useful. + +.H 3 "Location Record" +The \f(CWDwarf_Loc\fP type identifies a single atom of a location description +or a location expression. + +.DS +\f(CWtypedef struct { + Dwarf_Small lr_atom; + Dwarf_Unsigned lr_number; + Dwarf_Unsigned lr_number2; + Dwarf_Unsigned lr_offset; +} Dwarf_Loc;\fP +.DE + +The \f(CWlr_atom\fP identifies the atom corresponding to the \f(CWDW_OP_*\fP +definition in \fIdwarf.h\fP and it represents the operation to be performed +in order to locate the item in question. + +.P +The \f(CWlr_number\fP field is the operand to be used in the calculation +specified by the \f(CWlr_atom\fP field; not all atoms use this field. +Some atom operations imply signed numbers so it is necessary to cast +this to a \f(CWDwarf_Signed\fP type for those operations. + +.P +The \f(CWlr_number2\fP field is the second operand specified by the +\f(CWlr_atom\fP field; only \f(CWDW_OP_BREGX\fP has this field. Some +atom operations imply signed numbers so it may be necessary to cast +this to a \f(CWDwarf_Signed\fP type for those operations. + +.P +The \f(CWlr_offset\fP field is the byte offset (within the block the +location record came from) of the atom specified by the \f(CWlr_atom\fP +field. This is set on all atoms. This is useful for operations +\f(CWDW_OP_SKIP\fP and \f(CWDW_OP_BRA\fP. + +.H 3 "Location Description" +The \f(CWDwarf_Locdesc\fP type represents an ordered list of +\f(CWDwarf_Loc\fP records used in the calculation to locate +an item. Note that in many cases, the location can only be +calculated at runtime of the associated program. + +.DS +\f(CWtypedef struct { + Dwarf_Addr ld_lopc; + Dwarf_Addr ld_hipc; + Dwarf_Unsigned ld_cents; + Dwarf_Loc* ld_s; +} Dwarf_Locdesc;\fP +.DE + +The \f(CWld_lopc\fP and \f(CWld_hipc\fP fields provide an address range for +which this location descriptor is valid. Both of these fields are set to +\fIzero\fP if the location descriptor is valid throughout the scope of the +item it is associated with. These addresses are virtual memory addresses, +not offsets-from-something. The virtual memory addresses do not account +for dso movement (none of the pc values from libdwarf do that, it is up to +the consumer to do that). + +.P +The \f(CWld_cents\fP field contains a count of the number of \f(CWDwarf_Loc\fP +entries pointed to by the \f(CWld_s\fP field. + +.P +The \f(CWld_s\fP field points to an array of \f(CWDwarf_Loc\fP records. + +.H 3 "Data Block" +.SP +The \f(CWDwarf_Block\fP type is used to contain the value of an attribute +whose form is either \f(CWDW_FORM_block1\fP, \f(CWDW_FORM_block2\fP, +\f(CWDW_FORM_block4\fP, \f(CWDW_FORM_block8\fP, or \f(CWDW_FORM_block\fP. +Its intended use is to deliver the value for an attribute of any of these +forms. + +.DS +\f(CWtypedef struct { + Dwarf_Unsigned bl_len; + Dwarf_Ptr bl_data; +} Dwarf_Block;\fP +.DE + +.P +The \f(CWbl_len\fP field contains the length in bytes of the data pointed +to by the \f(CWbl_data\fP field. + +.P +The \f(CWbl_data\fP field contains a pointer to the uninterpreted data. +Since we use a \f(CWDwarf_Ptr\fP here one must copy the pointer to some +other type (typically an \f(CWunsigned char *\fP) so one can add increments +to index through the data. The data pointed to by \f(CWbl_data\fP is not +necessarily at any useful alignment. + +.H 3 "Frame Operation Codes: DWARF 2" +This interface is adequate for DWARF2 but not for DWARF3. +A separate interface usable for DWARF3 and for DWARF2 is described below. +.P +The DWARF2 \f(CWDwarf_Frame_Op\fP type is used to contain the data of a single +instruction of an instruction-sequence of low-level information from the +section containing frame information. This is ordinarily used by +Internal-level Consumers trying to print everything in detail. + +.DS +\f(CWtypedef struct { + Dwarf_Small fp_base_op; + Dwarf_Small fp_extended_op; + Dwarf_Half fp_register; + Dwarf_Signed fp_offset; + Dwarf_Offset fp_instr_offset; +} Dwarf_Frame_Op; +.DE + +\f(CWfp_base_op\fP is the 2-bit basic op code. \f(CWfp_extended_op\fP is +the 6-bit extended opcode (if \f(CWfp_base_op\fP indicated there was an +extended op code) and is zero otherwise. +.P +\f(CWfp_register\fP +is any (or the first) register value as defined +in the \f(CWCall Frame Instruction Encodings\fP figure +in the \f(CWdwarf\fP document. +If not used with the Op it is 0. +.P +\f(CWfp_offset\fP +is the address, delta, offset, or second register as defined +in the \f(CWCall Frame Instruction Encodings\fP figure +in the \f(CWdwarf\fP document. +If this is an \f(CWaddress\fP then the value should be cast to +\f(CW(Dwarf_Addr)\fP before being used. +In any implementation this field *must* be as large as the +larger of Dwarf_Signed and Dwarf_Addr for this to work properly. +If not used with the op it is 0. +.P +\f(CWfp_instr_offset\fP is the byte_offset (within the instruction +stream of the frame instructions) of this operation. It starts at 0 +for a given frame descriptor. + +.H 3 "Frame Regtable: DWARF 2" +This interface is adequate for DWARF2 but not for DWARF3. +A separate interface usable for DWARF3 and for DWARF2 is described below. +.P +The \f(CWDwarf_Regtable\fP type is used to contain the +register-restore information for all registers at a given +PC value. +Normally used by debuggers. +.DS +/* DW_REG_TABLE_SIZE must reflect the number of registers + *(DW_FRAME_LAST_REG_NUM) as defined in dwarf.h + */ +#define DW_REG_TABLE_SIZE +\f(CWtypedef struct { + struct { + Dwarf_Small dw_offset_relevant; + Dwarf_Half dw_regnum; + Dwarf_Addr dw_offset; + } rules[DW_REG_TABLE_SIZE]; +} Dwarf_Regtable;\fP +.DE +.P +The array is indexed by register number. +The field values for each index are described next. +For clarity we describe the field values for index rules[M] +(M being any legal array element index). +.P +\f(CWdw_offset_relevant\fP is non-zero to indicate the \f(CWdw_offset\fP +field is meaningful. If zero then the \f(CWdw_offset\fP is zero +and should be ignored. +.P +\f(CWdw_regnum \fPis the register number\fP applicable. +If \f(CWdw_offset_relevant\fP is zero, then this is the register +number of the register containing the value for register M. +If \f(CWdw_offset_relevant\fP is non-zero, then this is +the register number of the register to use as a base (M may be +DW_FRAME_CFA_COL, for example) and the \f(CWdw_offset\fP +value applies. The value of register M is therefore +the value of register \f(CWdw_regnum\vP . +.P +\f(CWdw_offset\fP should be ignored if \f(CWdw_offset_relevant\fP is zero. +If \f(CWdw_offset_relevant\fP is non-zero, then +the consumer code should add the value to +the value of the register \f(CWdw_regnum\fP to produce the +value. + +.H 3 "Frame Operation Codes: DWARF 3 (and DWARF2)" +This interface is adequate for DWARF3 and for DWARF2. +It is new in libdwarf in April 2006. +.P +The DWARF2 \f(CWDwarf_Frame_Op3\fP type is used to contain the data of a single +instruction of an instruction-sequence of low-level information from the +section containing frame information. This is ordinarily used by +Internal-level Consumers trying to print everything in detail. + +.DS +\f(CWtypedef struct { + Dwarf_Small fp_base_op; + Dwarf_Small fp_extended_op; + Dwarf_Half fp_register; + + /* Value may be signed, depends on op. + Any applicable data_alignment_factor has + not been applied, this is the raw offset. */ + Dwarf_Unsigned fp_offset_or_block_len; + Dwarf_Small *fp_expr_block; + + Dwarf_Off fp_instr_offset; +} Dwarf_Frame_Op3;\fP +.DE + +\f(CWfp_base_op\fP is the 2-bit basic op code. \f(CWfp_extended_op\fP is +the 6-bit extended opcode (if \f(CWfp_base_op\fP indicated there was an +extended op code) and is zero otherwise. +.P +\f(CWfp_register\fP +is any (or the first) register value as defined +in the \f(CWCall Frame Instruction Encodings\fP figure +in the \f(CWdwarf\fP document. +If not used with the Op it is 0. +.P +\f(CWfp_offset_or_block_len\fP +is the address, delta, offset, or second register as defined +in the \f(CWCall Frame Instruction Encodings\fP figure +in the \f(CWdwarf\fP document. Or (depending on the op, it +may be the length of the dwarf-expression block pointed to +by \f(CWfp_expr_block\fP. +If this is an \f(CWaddress\fP then the value should be cast to +\f(CW(Dwarf_Addr)\fP before being used. +In any implementation this field *must* be as large as the +larger of Dwarf_Signed and Dwarf_Addr for this to work properly. +If not used with the op it is 0. +.P +\f(CWfp_expr_block\fP (if applicable to the op) +points to a dwarf-expression block whch is \f(CWfp_offset_or_block_len\fP +bytes long. +.P +\f(CWfp_instr_offset\fP is the byte_offset (within the instruction +stream of the frame instructions) of this operation. It starts at 0 +for a given frame descriptor. + +.H 3 "Frame Regtable: DWARF 3" +This interface is adequate for DWARF3 and for DWARF2. +It is new in libdwarf as of April 2006. +.P +The \f(CWDwarf_Regtable3\fP type is used to contain the +register-restore information for all registers at a given +PC value. +Normally used by debuggers. +.DS +\f(CWtypedef struct Dwarf_Regtable_Entry3_s { + Dwarf_Small dw_offset_relevant; + Dwarf_Small dw_value_type; + Dwarf_Half dw_regnum; + Dwarf_Unsigned dw_offset_or_block_len; + Dwarf_Ptr dw_block_ptr; +}Dwarf_Regtable_Entry3; + +typedef struct Dwarf_Regtable3_s { + struct Dwarf_Regtable_Entry3_s rt3_cfa_rule; + + Dwarf_Half rt3_reg_table_size; + struct Dwarf_Regtable_Entry3_s * rt3_rules; +} Dwarf_Regtable3;\fP + +.DE +.P +The array is indexed by register number. +The field values for each index are described next. +For clarity we describe the field values for index rules[M] +(M being any legal array element index). +(DW_FRAME_CFA_COL3 DW_FRAME_SAME_VAL, DW_FRAME_UNDEFINED_VAL +are not legal array indexes, nor is any index < 0 or > +rt3_reg_table_size); +The caller of routines using this +struct must create data space for rt3_reg_table_size entries +of struct Dwarf_Regtable_Entry3_s and arrange that +rt3_rules points to that space and that rt3_reg_table_size +is set correctly. The caller need not (but may) +initialize the contents of the rt3_cfa_rule or the rt3_rules array. +The following applies to each rt3_rules rule M: +.P +.in +4 +\f(CWdw_regnum\fP is the register number applicable. +If \f(CWdw_regnum\fP is DW_FRAME_UNDEFINED_VAL, then the +register I has undefined value. +If \f(CWdw_regnum\fP is DW_FRAME_SAME_VAL, then the +register I has the same value as in the previous frame. +.P +If \f(CWdw_regnum\fP is neither of these two, then the following apply: +.P +.P +\f(CWdw_value_type\fP determines the meaning of the other fields. +It is one of DW_EXPR_OFFSET (0), +DW_EXPR_VAL_OFFSET(1), DW_EXPR_EXPRESSION(2) or +DW_EXPR_VAL_EXPRESSION(3). + +.P +If \f(CWdw_value_type\fP is DW_EXPR_OFFSET (0) then +this is as in DWARF2 and the offset(N) rule or the register(R) +rule +of the DWARF3 and DWARF2 document applies. +The value is either: +.in +4 +If \f(CWdw_offset_relevant\fP is non-zero, then \f(CWdw_regnum\fP +is effectively ignored but must be identical to +DW_FRAME_CFA_COL3 and the \f(CWdw_offset\fP value applies. +The value of register M is therefore +the value of CFA plus the value +of \f(CWdw_offset\fP. The result of the calculation +is the address in memory where the value of register M resides. +This is the offset(N) rule of the DWARF2 and DWARF3 documents. +.P +\f(CWdw_offset_relevant\fP is zero it indicates the \f(CWdw_offset\fP +field is not meaningful. +The value of register M is +the value currently in register \f(CWdw_regnum\fP (the +value DW_FRAME_CFA_COL3 must not appear, only real registers). +This is the register(R) rule of the DWARF3 spec. +.in -4 + +.P +If \f(CWdw_value_type\fP is DW_EXPR_OFFSET (1) then +this is the the val_offset(N) rule of the DWARF3 spec applies. +The calculation is identical to that of DW_EXPR_OFFSET (0) +but the value is interpreted as the value of register M +(rather than the address where register M's value is stored). +.P +If \f(CWdw_value_type\fP is DW_EXPR_EXPRESSION (2) then +this is the the expression(E) rule of the DWARF3 document. +.P +.in +4 +\f(CWdw_offset_or_block_len\fP is the length in bytes of +the in-memory block pointed at by \f(CWdw_block_ptr\fP. +\f(CWdw_block_ptr\fP is a DWARF expression. +Evaluate that expression and the result is the address +where the previous value of register M is found. +.in -4 +.P +If \f(CWdw_value_type\fP is DW_EXPR_VAL_EXPRESSION (3) then +this is the the val_expression(E) rule of the DWARF3 spec. +.P +.in +4 +\f(CWdw_offset_or_block_len\fP is the length in bytes of +the in-memory block pointed at by \f(CWdw_block_ptr\fP. +\f(CWdw_block_ptr\fP is a DWARF expression. +Evaluate that expression and the result is the +previous value of register M. +.in -4 +.P +The rule \f(CWrt3_cfa_rule\fP is the current value of +the CFA. It is interpreted exactly like +any register M rule (as described just above) except that +\f(CWdw_regnum\fP cannot be CW_FRAME_CFA_REG3 or +DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL but must +be a real register number. +.in -4 + + + +.H 3 "Macro Details Record" +The \f(CWDwarf_Macro_Details\fP type gives information about +a single entry in the .debug.macinfo section. +.DS +\f(CWstruct Dwarf_Macro_Details_s { + Dwarf_Off dmd_offset; + Dwarf_Small dmd_type; + Dwarf_Signed dmd_lineno; + Dwarf_Signed dmd_fileindex; + char * dmd_macro; +}; +typedef struct Dwarf_Macro_Details_s Dwarf_Macro_Details; +.DE +.P +\f(CWdmd_offset\fP is the byte offset, within the .debug_macinfo +section, of this macro information. +.P +\f(CWdmd_type\fP is the type code of this macro info entry +(or 0, the type code indicating that this is the end of +macro information entries for a compilation unit. +See \f(CWDW_MACINFO_define\fP, etc in the DWARF document. +.P +\f(CWdmd_lineno\fP is the line number where this entry was found, +or 0 if there is no applicable line number. +.P +\f(CWdmd_fileindex\fP is the file index of the file involved. +This is only guaranteed meaningful on a \f(CWDW_MACINFO_start_file\fP +\f(CWdmd_type\fP. Set to -1 if unknown (see the functional +interface for more details). +.P +\f(CWdmd_macro\fP is the applicable string. +For a \f(CWDW_MACINFO_define\fP +this is the macro name and value. +For a +\f(CWDW_MACINFO_undef\fP, or +this is the macro name. +For a +\f(CWDW_MACINFO_vendor_ext\fP +this is the vendor-defined string value. +For other \f(CWdmd_type\fPs this is 0. + +.H 2 "Opaque Types" +The opaque types declared in \fIlibdwarf.h\fP are used as descriptors +for queries against DWARF information stored in various debugging +sections. Each time an instance of an opaque type is returned as a +result of a \fIlibdwarf\fP operation (\f(CWDwarf_Debug\fP excepted), +it should be free'd, using \f(CWdwarf_dealloc()\fP when it is no longer +of use (read the following documentation for details, as in at least +one case there is a special routine provided for deallocation +and \f(CWdwarf_dealloc()\fP is not directly called: +see \f(CWdwarf_srclines()\fP). +Some functions return a number of instances of an opaque type +in a block, by means of a pointer to the block and a count of the number +of opaque descriptors in the block: +see the function description for deallocation rules for such functions. +The list of opaque types defined +in \fIlibdwarf.h\fP that are pertinent to the Consumer Library, and their +intended use is described below. + +.DS +\f(CWtypedef struct Dwarf_Debug_s* Dwarf_Debug;\fP +.DE +An instance of the \f(CWDwarf_Debug\fP type is created as a result of a +successful call to \f(CWdwarf_init()\fP, or \f(CWdwarf_elf_init()\fP, +and is used as a descriptor for subsequent access to most \f(CWlibdwarf\fP +functions on that object. The storage pointed to by this descriptor +should be not be free'd, using the \f(CWdwarf_dealloc()\fP function. +Instead free it with \f(CWdwarf_finish()\fP. +.P + +.DS +\f(CWtypedef struct Dwarf_Die_s* Dwarf_Die;\fP +.DE +An instance of a \f(CWDwarf_Die\fP type is returned from a successful +call to the \f(CWdwarf_siblingof()\fP, \f(CWdwarf_child\fP, or +\f(CWdwarf_offdie()\fP function, and is used as a descriptor for queries +about information related to that DIE. The storage pointed to by this +descriptor should be free'd, using \f(CWdwarf_dealloc()\fP with the allocation +type \f(CWDW_DLA_DIE\fP when no longer needed. + +.DS +\f(CWtypedef struct Dwarf_Line_s* Dwarf_Line;\fP +.DE +Instances of \f(CWDwarf_Line\fP type are returned from a successful call +to the \f(CWdwarf_srclines()\fP function, and are used as descriptors for +queries about source lines. The storage pointed to by these descriptors +should be individually free'd, using \f(CWdwarf_dealloc()\fP with the +allocation type \f(CWDW_DLA_LINE\fP when no longer needed. + +.DS +\f(CWtypedef struct Dwarf_Global_s* Dwarf_Global;\fP +.DE +Instances of \f(CWDwarf_Global\fP type are returned from a successful +call to the \f(CWdwarf_get_globals()\fP function, and are used as +descriptors for queries about global names (pubnames). + +.DS +\f(CWtypedef struct Dwarf_Weak_s* Dwarf_Weak;\fP +.DE +Instances of \f(CWDwarf_Weak\fP type are returned from a successful call +to the +SGI-specific \f(CWdwarf_get_weaks()\fP +function, and are used as descriptors for +queries about weak names. The storage pointed to by these descriptors +should be individually free'd, using \f(CWdwarf_dealloc()\fP with the +allocation type +\f(CWDW_DLA_WEAK_CONTEXT\fP +(or +\f(CWDW_DLA_WEAK\fP, an older name, supported for compatibility) +when no longer needed. + +.DS +\f(CWtypedef struct Dwarf_Func_s* Dwarf_Func;\fP +.DE +Instances of \f(CWDwarf_Func\fP type are returned from a successful +call to the +SGI-specific \f(CWdwarf_get_funcs()\fP +function, and are used as +descriptors for queries about static function names. + +.DS +\f(CWtypedef struct Dwarf_Type_s* Dwarf_Type;\fP +.DE +Instances of \f(CWDwarf_Type\fP type are returned from a successful call +to the +SGI-specific \f(CWdwarf_get_types()\fP +function, and are used as descriptors for +queries about user defined types. + +.DS +\f(CWtypedef struct Dwarf_Var_s* Dwarf_Var;\fP +.DE +Instances of \f(CWDwarf_Var\fP type are returned from a successful call +to the SGI-specific \f(CWdwarf_get_vars()\fP +function, and are used as descriptors for +queries about static variables. + +.DS +\f(CWtypedef struct Dwarf_Error_s* Dwarf_Error;\fP +.DE +This descriptor points to a structure that provides detailed information +about errors detected by \f(CWlibdwarf\fP. Users typically provide a +location for \f(CWlibdwarf\fP to store this descriptor for the user to +obtain more information about the error. The storage pointed to by this +descriptor should be free'd, using \f(CWdwarf_dealloc()\fP with the +allocation type \f(CWDW_DLA_ERROR\fP when no longer needed. + +.DS +\f(CWtypedef struct Dwarf_Attribute_s* Dwarf_Attribute;\fP +.DE +Instances of \f(CWDwarf_Attribute\fP type are returned from a successful +call to the \f(CWdwarf_attrlist()\fP, or \f(CWdwarf_attr()\fP functions, +and are used as descriptors for queries about attribute values. The storage +pointed to by this descriptor should be individually free'd, using +\f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ATTR\fP when +no longer needed. + +.DS +\f(CWtypedef struct Dwarf_Abbrev_s* Dwarf_Abbrev;\fP +.DE +An instance of a \f(CWDwarf_Abbrev\fP type is returned from a successful +call to \f(CWdwarf_get_abbrev()\fP, and is used as a descriptor for queries +about abbreviations in the .debug_abbrev section. The storage pointed to +by this descriptor should be free'd, using \f(CWdwarf_dealloc()\fP with the +allocation type \f(CWDW_DLA_ABBREV\fP when no longer needed. + +.DS +\f(CWtypedef struct Dwarf_Fde_s* Dwarf_Fde;\fP +.DE +Instances of \f(CWDwarf_Fde\fP type are returned from a successful call +to the \f(CWdwarf_get_fde_list()\fP, \f(CWdwarf_get_fde_for_die()\fP, or +\f(CWdwarf_get_fde_at_pc()\fP functions, and are used as descriptors for +queries about frames descriptors. + +.DS +\f(CWtypedef struct Dwarf_Cie_s* Dwarf_Cie;\fP +.DE +Instances of \f(CWDwarf_Cie\fP type are returned from a successful call +to the \f(CWdwarf_get_fde_list()\fP function, and are used as descriptors +for queries about information that is common to several frames. + +.DS +\f(CWtypedef struct Dwarf_Arange_s* Dwarf_Arange;\fP +.DE +Instances of \f(CWDwarf_Arange\fP type are returned from successful calls +to the \f(CWdwarf_get_aranges()\fP, or \f(CWdwarf_get_arange()\fP functions, +and are used as descriptors for queries about address ranges. The storage +pointed to by this descriptor should be individually free'd, using +\f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ARANGE\fP when +no longer needed. + +.H 1 "Error Handling" +The method for detection and disposition of error conditions that arise +during access of debugging information via \fIlibdwarf\fP is consistent +across all \fIlibdwarf\fP functions that are capable of producing an +error. This section describes the method used by \fIlibdwarf\fP in +notifying client programs of error conditions. + +.P +Most functions within \fIlibdwarf\fP accept as an argument a pointer to +a \f(CWDwarf_Error\fP descriptor where a \f(CWDwarf_Error\fP descriptor +is stored if an error is detected by the function. Routines in the client +program that provide this argument can query the \f(CWDwarf_Error\fP +descriptor to determine the nature of the error and perform appropriate +processing. + +.P +A client program can also specify a function to be invoked upon detection +of an error at the time the library is initialized (see \f(CWdwarf_init()\fP). +When a \fIlibdwarf\fP routine detects an error, this function is called +with two arguments: a code indicating the nature of the error and a pointer +provided by the client at initialization (again see \f(CWdwarf_init()\fP). +This pointer argument can be used to relay information between the error +handler and other routines of the client program. A client program can +specify or change both the error handling function and the pointer argument +after initialization using \f(CWdwarf_seterrhand()\fP and +\f(CWdwarf_seterrarg()\fP. + +.P +In the case where \fIlibdwarf\fP functions are not provided a pointer +to a \f(CWDwarf_Error\fP descriptor, and no error handling function was +provided at initialization, \fIlibdwarf\fP functions terminate execution +by calling \f(CWabort(3C)\fP. + +.P +The following lists the processing steps taken upon detection of an +error: +.AL 1 +.LI +Check the \f(CWerror\fP argument; if not a \fINULL\fP pointer, allocate +and initialize a \f(CWDwarf_Error\fP descriptor with information describing +the error, place this descriptor in the area pointed to by \f(CWerror\fP, +and return a value indicating an error condition. +.LI +If an \f(CWerrhand\fP argument was provided to \f(CWdwarf_init()\fP +at initialization, call \f(CWerrhand()\fP passing it the error descriptor +and the value of the \f(CWerrarg\fP argument provided to \f(CWdwarf_init()\fP. +If the error handling function returns, return a value indicating an +error condition. +.LI +Terminate program execution by calling \f(CWabort(3C)\fP. +.LE +.SP + +In all cases, it is clear from the value returned from a function +that an error occurred in executing the function, since +DW_DLV_ERROR is returned. +.P +As can be seen from the above steps, the client program can provide +an error handler at initialization, and still provide an \f(CWerror\fP +argument to \fIlibdwarf\fP functions when it is not desired to have +the error handler invoked. + +.P +If a \f(CWlibdwarf\fP function is called with invalid arguments, the +behaviour is undefined. In particular, supplying a \f(CWNULL\fP pointer +to a \f(CWlibdwarf\fP function (except where explicitly permitted), +or pointers to invalid addresses or uninitialized data causes undefined +behaviour; the return value in such cases is undefined, and the function +may fail to invoke the caller supplied error handler or to return a +meaningful error number. Implementations also may abort execution for +such cases. + +.P +.H 2 "Returned values in the functional interface" +Values returned by \f(CWlibdwarf\fP functions to indicate +success and errors +.nr aX \n(Fg+1 +are enumerated in Figure \n(aX. +The \f(CWDW_DLV_NO_ENTRY\fP +case is useful for functions +need to indicate that while there was no data to return +there was no error either. +For example, \f(CWdwarf_siblingof()\fP +may return \f(CWDW_DLV_NO_ENTRY\fP to indicate that that there was +no sibling to return. +.DS +.TS +center box, tab(:); +lfB cfB lfB +l c l. +SYMBOLIC NAME:VALUE:MEANING +_ +DW_DLV_ERROR:1:Error +DW_DLV_OK:0:Successful call +DW_DLV_NO_ENTRY:-1:No applicable value +.TE +.FG "Error Indications" +.DE +.P +Each function in the interface that returns a value returns one +of the integers in the above figure. +.P +If \f(CWDW_DLV_ERROR\fP is returned and a pointer to a \f(CWDwarf_Error\fP +pointer is passed to the function, then a Dwarf_Error handle is returned +thru the pointer. No other pointer value in the interface returns a value. +After the \f(CWDwarf_Error\fP is no longer of interest, +a \f(CWdwarf_dealloc(dbg,dw_err,DW_DLA_ERROR)\fP on the error +pointer is appropriate to free any space used by the error information. +.P +If \f(CWDW_DLV_NO_ENTRY\fP is returned no pointer value in the +interface returns a value. +.P +If \f(CWDW_DLV_OK\fP is returned the \f(CWDwarf_Error\fP pointer, if +supplied, is not touched, but any other values to be returned +through pointers are returned. +In this case calls (depending on the exact function +returning the error) to \f(CWdwarf_dealloc()\fP may be appropriate +once the particular pointer returned is no longer of interest. +.P +Pointers passed to allow values to be returned thru them are +uniformly the last pointers +in each argument list. +.P +All the interface functions are defined from the point of view of +the writer-of-the-library (as is traditional for UN*X library +documentation), not from the point of view of the user of the library. +The caller might code: +.P +.DS +Dwarf_Line line; +Dwarf_Signed ret_loff; +Dwarf_Error err; +int retval = dwarf_lineoff(line,&ret_loff,&err); +.DE +for the function defined as +.P +.DS +int dwarf_lineoff(Dwarf_Line line,Dwarf_Signed *return_lineoff, + Dwarf_Error* err); +.DE +and this document refers to the function as +returning the value thru *err or *return_lineoff or +uses the phrase "returns in +the location pointed to by err". +Sometimes other similar phrases are used. + +.H 1 "Memory Management" +Several of the functions that comprise \fIlibdwarf\fP return pointers +(opaque descriptors) to structures that have been dynamically allocated +by the library. To aid in the management of dynamic memory, the function +\f(CWdwarf_dealloc()\fP is provided to free storage allocated as a result +of a call to a \fIlibdwarf\fP function. This section describes the strategy +that should be taken by a client program in managing dynamic storage. + +.H 2 "Read-only Properties" +All pointers (opaque descriptors) returned by or as a result of a +\fIlibdwarf Consumer Library\fP +call should be assumed to point to read-only memory. +The results are undefined for \fIlibdwarf\fP clients that attempt +to write to a region pointed to by a value returned by a +\fIlibdwarf Consumer Library\fP +call. + +.H 2 "Storage Deallocation" +See the section "Returned values in the functional interface", +above, for the general rules where +calls to \f(CWdwarf_dealloc()\fP +is appropriate. +.P +In some cases the pointers returned by a \fIlibdwarf\fP call are pointers +to data which is not free-able. +The library knows from the allocation type +provided to it whether the space is freeable or not and will not free +inappropriately when \f(CWdwarf_dealloc()\fP is called. +So it is vital +that \f(CWdwarf_dealloc()\fP be called with the proper allocation type. +.P +For most storage allocated by \fIlibdwarf\fP, the client can free the +storage for reuse by calling \f(CWdwarf_dealloc()\fP, providing it with +the \f(CWDwarf_Debug\fP descriptor specifying the object for which the +storage was allocated, a pointer to the area to be free-ed, and an +identifier that specifies what the pointer points to (the allocation +type). For example, to free a \f(CWDwarf_Die die\fP belonging the the +object represented by \f(CWDwarf_Debug dbg\fP, allocated by a call to +\f(CWdwarf_siblingof()\fP, the call to \f(CWdwarf_dealloc()\fP would be: +.DS + \f(CWdwarf_dealloc(dbg, die, DW_DLA_DIE);\fP +.DE + +To free storage allocated in the form of a list of pointers (opaque +descriptors), each member of the list should be deallocated, followed +by deallocation of the actual list itself. The following code fragment +uses an invocation of \f(CWdwarf_attrlist()\fP as an example to illustrate +a technique that can be used to free storage from any \fIlibdwarf\fP +routine that returns a list: +.DS +\f(CWDwarf_Unsigned atcnt; +Dwarf_Attribute *atlist; +int errv; + +errv = dwarf_attrlist(somedie, &atlist,&atcnt, &error); +if (errv == DW_DLV_OK) { + + for (i = 0; i < atcnt; ++i) { + /* use atlist[i] */ + dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR); + } + dwarf_dealloc(dbg, atlist, DW_DLA_LIST); +}\fP +.DE + +The \f(CWDwarf_Debug\fP returned from \f(CWdwarf_init()\fP +or \f(CWdwarf_elf_init()\fP +cannot be free'd using \f(CWdwarf_dealloc()\fP. +The function \f(CWdwarf_finish()\fP will deallocate all dynamic storage +associated with an instance of a \f(CWDwarf_Debug\fP type. In particular, +it will deallocate all dynamically allocated space associated with the +\f(CWDwarf_Debug\fP descriptor, and finally make the descriptor invalid. + +An \f(CWDwarf_Error\fP returned from \f(CWdwarf_init()\fP +or \f(CWdwarf_elf_init()\fP +in case of a failure cannot be free'd +using \f(CWdwarf_dealloc()\fP. +The only way to free the \f(CWDwarf_Error\fP from either of those +calls is to use \f2free(3)\fP directly. +Every \f(CWDwarf_Error\fP must be free'd +by \f(CWdwarf_dealloc()\fP except those +returned by \f(CWdwarf_init()\fP +or \f(CWdwarf_elf_init()\fP. + +.P +The codes that identify the storage pointed to in calls to +.nr aX \n(Fg+1 +\f(CWdwarf_dealloc()\fP are described in figure \n(aX. +.DS +.TS +center box, tab(:); +lfB lfB +l l. +IDENTIFIER:USED TO FREE +_ +DW_DLA_STRING : char* +DW_DLA_LOC : Dwarf_Loc +DW_DLA_LOCDESC : Dwarf_Locdesc +DW_DLA_ELLIST : Dwarf_Ellist (not used) +DW_DLA_BOUNDS : Dwarf_Bounds (not used) +DW_DLA_BLOCK : Dwarf_Block +DW_DLA_DEBUG : Dwarf_Debug (do not use) +DW_DLA_DIE : Dwarf_Die +DW_DLA_LINE : Dwarf_Line +DW_DLA_ATTR : Dwarf_Attribute +DW_DLA_TYPE : Dwarf_Type (not used) +DW_DLA_SUBSCR : Dwarf_Subscr (not used) +DW_DLA_GLOBAL_CONTEXT : Dwarf_Global +DW_DLA_ERROR : Dwarf_Error +DW_DLA_LIST : a list of opaque descriptors +DW_DLA_LINEBUF : Dwarf_Line* (not used) +DW_DLA_ARANGE : Dwarf_Arange +DW_DLA_ABBREV : Dwarf_Abbrev +DW_DLA_FRAME_OP : Dwarf_Frame_Op +DW_DLA_CIE : Dwarf_Cie +DW_DLA_FDE : Dwarf_Fde +DW_DLA_LOC_BLOCK : Dwarf_Loc Block +DW_DLA_FRAME_BLOCK : Dwarf_Frame Block (not used) +DW_DLA_FUNC_CONTEXT : Dwarf_Func +DW_DLA_TYPENAME_CONTEXT : Dwarf_Type +DW_DLA_VAR_CONTEXT : Dwarf_Var +DW_DLA_WEAK_CONTEXT : Dwarf_Weak +DW_DLA_PUBTYPES_CONTEXT : Dwarf_Pubtype +.TE +.FG "Allocation/Deallocation Identifiers" +.DE + +.P +.H 1 "Functional Interface" +This section describes the functions available in the \fIlibdwarf\fP +library. Each function description includes its definition, followed +by one or more paragraph describing the function's operation. + +.P +The following sections describe these functions. + +.H 2 "Initialization Operations" +These functions are concerned with preparing an object file for subsequent +access by the functions in \fIlibdwarf\fP and with releasing allocated +resources when access is complete. + +.H 3 "dwarf_init()" + +.DS +\f(CWint dwarf_init( + int fd, + Dwarf_Unsigned access, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, + Dwarf_Debug * dbg, + Dwarf_Error *error)\fP +.DE +When it returns \f(CWDW_DLV_OK\fP, +the function \f(CWdwarf_init()\fP returns thru +\f(CWdbg\fP a \f(CWDwarf_Debug\fP descriptor +that represents a handle for accessing debugging records associated with +the open file descriptor \f(CWfd\fP. +\f(CWDW_DLV_NO_ENTRY\fP is returned if the object +does not contain DWARF debugging information. +\f(CWDW_DLV_ERROR\fP is returned if +an error occurred. +The +\f(CWaccess\fP argument indicates what access is allowed for the section. +The \f(CWDW_DLC_READ\fP parameter is valid +for read access (only read access is defined or discussed in this +document). +The \f(CWerrhand\fP +argument is a pointer to a function that will be invoked whenever an error +is detected as a result of a \fIlibdwarf\fP operation. The \f(CWerrarg\fP +argument is passed as an argument to the \f(CWerrhand\fP function. +The file +descriptor associated with the \f(CWfd\fP argument must refer to an ordinary +file (i.e. not a pipe, socket, device, /proc entry, etc.), be opened with +the at least as much permission as specified by the \f(CWaccess\fP argument, +and cannot be closed or used as an argument to any system calls by the +client until after \f(CWdwarf_finish()\fP is called. +The seek position of +the file associated with \f(CWfd\fP is undefined upon return of +\f(CWdwarf_init()\fP. + +With SGI IRIX, by default it is allowed that the app +\f(CWclose()\fP \f(CWfd\fP immediately after calling \f(CWdwarf_init()\fP, +but that is not a portable approach (that it +works is an accidental +side effect of the fact that SGI IRIX uses \f(CWELF_C_READ_MMAP\fP +in its hidden internal call to \f(CWelf_begin()\fP). +The portable approach is to consider that \f(CWfd\fP +must be left open till after the corresponding dwarf_finish() call +has returned. + +Since \f(CWdwarf_init()\fP uses the same error handling processing as other +\fIlibdwarf\fP functions (see \fIError Handling\fP above), client programs +will generally supply an \f(CWerror\fP parameter to bypass the default actions +during initialization unless the default actions are appropriate. + +.H 3 "dwarf_elf_init()" +.DS +\f(CWint dwarf_elf_init( + Elf * elf_file_pointer, + Dwarf_Unsigned access, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, + Dwarf_Debug * dbg, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_elf_init()\fP is identical to \f(CWdwarf_init()\fP +except that an open \f(CWElf *\fP pointer is passed instead of a file +descriptor. +In systems supporting \f(CWELF\fP object files this may be +more space or time-efficient than using \f(CWdwarf_init()\fP. +The client is allowed to use the \f(CWElf *\fP pointer +for its own purposes without restriction during the time the +\f(CWDwarf_Debug\fP +is open, except that the client should not \f(CWelf_end()\fP the +pointer till after \f(CWdwarf_finish\fP is called. + +.H 3 "dwarf_get_elf()" +.DS +\f(CWint dwarf_get_elf( + Dwarf_Debug dbg, + Elf ** elf, + Dwarf_Error *error)\fP +.DE +When it returns \f(CWDW_DLV_OK\fP, +the function \f(CWdwarf_get_elf()\fP returns thru the +pointer \f(CWelf\fP the \f(CWElf *\fP handle +used to access the object represented by the \f(CWDwarf_Debug\fP +descriptor \f(CWdbg\fP. It returns \f(CWDW_DLV_ERROR\fP on error. + +Because \f(CWint dwarf_init()\fP opens an Elf descriptor +on its fd and \f(CWdwarf_finish()\fP does not close that +descriptor, an app should use \f(CWdwarf_get_elf\fP +and should call \f(CWelf_end\fP with the pointer returned +thru the \f(CWElf**\fP handle created by \f(CWint dwarf_init()\fP. + +This function is not meaningful for a system that does not use the +Elf format for objects. + +.H 3 "dwarf_finish()" +.DS +\f(CWint dwarf_finish( + Dwarf_Debug dbg, + Dwarf_Error *error)\fP +.DE +The function +\f(CWdwarf_finish()\fP releases all \fILibdwarf\fP internal resources +associated with the descriptor \f(CWdbg\fP, and invalidates \f(CWdbg\fP. +It returns \f(CWDW_DLV_ERROR\fP if there is an error during the +finishing operation. It returns \f(CWDW_DLV_OK\fP +for a successful operation. + +Because \f(CWint dwarf_init()\fP opens an Elf descriptor +on its fd and \f(CWdwarf_finish()\fP does not close that +descriptor, an app should use \f(CWdwarf_get_elf\fP +and should call \f(CWelf_end\fP with the pointer returned +thru the \f(CWElf**\fP handle created by \f(CWint dwarf_init()\fP. + +.H 2 "Debugging Information Entry Delivery Operations" +These functions are concerned with accessing debugging information +entries. + +.H 3 "Debugging Information Entry Debugger Delivery Operations" + +.H 3 "dwarf_next_cu_header()" +.DS +\f(CWint dwarf_next_cu_header( + Dwarf_debug dbg, + Dwarf_Unsigned *cu_header_length, + Dwarf_Half *version_stamp, + Dwarf_Unsigned *abbrev_offset, + Dwarf_Half *address_size, + Dwarf_Unsigned *next_cu_header, + Dwarf_Error *error); +.DE +The function +\f(CWdwarf_next_cu_header()\fP returns \f(CWDW_DLV_ERROR\fP +if it fails, and +\f(CWDW_DLV_OK\fP if it succeeds. +.P +If it succeeds, \f(CW*next_cu_header\fP is set to +the offset in the .debug_info section of the next +compilation-unit header if it succeeds. On reading the last +compilation-unit header in the .debug_info section it contains +the size of the .debug_info section. +The next call to +\f(CWdwarf_next_cu_header()\fP returns \f(CWDW_DLV_NO_ENTRY\fP +without reading a +compilation-unit or setting \f(CW*next_cu_header\fP. +Subsequent calls to \f(CWdwarf_next_cu_header()\fP +repeat the cycle by reading the first compilation-unit and so on. +.P +The other +values returned through pointers are the values in the compilation-unit +header. If any of \f(CWcu_header_length\fP, \f(CWversion_stamp\fP, +\f(CWabbrev_offset\fP, or \f(CWaddress_size\fP is \f(CWNULL\fP, the +argument is ignored (meaning it is not an error to provide a +\f(CWNULL\fP pointer). + +.H 3 "dwarf_siblingof()" +.DS +\f(CWint dwarf_siblingof( + Dwarf_Debug dbg, + Dwarf_Die die, + Dwarf_Die *return_sib, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_siblingof()\fP +returns \f(CWDW_DLV_ERROR\fP and sets the \f(CWerror\fP pointer on error. +If there is no sibling it returns \f(CWDW_DLV_NO_ENTRY\fP. +When it succeeds, +\f(CWdwarf_siblingof()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_sib\fP to the \f(CWDwarf_Die\fP +descriptor of the sibling of \f(CWdie\fP. +If \f(CWdie\fP is \fINULL\fP, the \f(CWDwarf_Die\fP descriptor of the +first die in the compilation-unit is returned. +This die has the +\f(CWDW_TAG_compile_unit\fP tag. +.H 3 "dwarf_child()" +.DS +\f(CWint dwarf_child( + Dwarf_Die die, + Dwarf_Die *return_kid, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_child()\fP +returns \f(CWDW_DLV_ERROR\fP and sets the \f(CWerror\fP die on error. +If there is no child it returns \f(CWDW_DLV_NO_ENTRY\fP. +When it succeeds, +\f(CWdwarf_child()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_kid\fP +to the \f(CWDwarf_Die\fP descriptor +of the first child of \f(CWdie\fP. +The function +\f(CWdwarf_siblingof()\fP can be used with the return value of +\f(CWdwarf_child()\fP to access the other children of \f(CWdie\fP. + +.H 3 "dwarf_offdie()" +.DS +\f(CWint dwarf_offdie( + Dwarf_Debug dbg, + Dwarf_Off offset, + Dwarf_Die *return_die, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_offdie()\fP +returns \f(CWDW_DLV_ERROR\fP and sets the \f(CWerror\fP die on error. +When it succeeds, +\f(CWdwarf_offdie()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_die\fP +to the +the \f(CWDwarf_Die\fP +descriptor of the debugging information entry at \f(CWoffset\fP in +the section containing debugging information entries i.e the .debug_info +section. +A return of \f(CWDW_DLV_NO_ENTRY\fP +means that the \f(CWoffset\fP in the section is of a byte containing +all 0 bits, indicating that there +is no abbreviation code. Meaning this 'die offset' is not +the offset of a real die, but is instead an offset of a null die, +a padding die, or of some random zero byte: this should +not be returned in normal use. +It is the user's +responsibility to make sure that \f(CWoffset\fP is the start of a valid +debugging information entry. The result of passing it an invalid +offset could be chaos. + +.\"#if 0 +.\".H 3 "Debugging Entry Delivery High-level Operations" +.\"The following "higher level" operations are typically not used by +.\"debuggers or DWARF prettyprinters. A disassembler (for example) +.\"might find them useful. +.\" +.\".DS +.\"\f(CWDwarf_Die dwarf_pcfile( +.\" Dwarf_Debug dbg, +.\" Dwarf_Addr pc, +.\" Dwarf_Error *error)\fP +.\".DE +.\"The function \f(CWdwarf_pcfile()\fP returns the \f(CWDwarf_Die\fP +.\"descriptor of the compilation unit debugging information entry that +.\"contains the address of \f(CWpc\fP. It returns \fINULL\fP if no +.\"entry exists or an error occurred. Currently compilation unit +.\"debugging information entries are defined as those having a tag of: +.\"\f(CWDW_TAG_compile_unit\fP. This function is currently unimplemented. +.\" +.\".DS +.\"\f(CWDwarf_Die dwarf_pcsubr( +.\" Dwarf_Debug dbg, +.\" Dwarf_Addr pc, +.\" Dwarf_Error *error)\fP +.\".DE +.\"The function +.\"\f(CWdwarf_pcsubr()\fP returns the \f(CWDwarf_Die\fP descriptor of the +.\"subroutine debugging entry that contains the address of \f(CWpc\fP. It +.\"returns \fINULL\fP if no entry exists or an error occurred. Currently +.\"subroutine debugging information entries are defined as those having a +.\"tag of: \f(CWDW_TAG_subprogram\fP, or \f(CWTAG_inlined_subroutine\fP. +.\"This function is currently unimplemented. +.\" +.\".DS +.\"\f(CWDwarf_Die dwarf_pcscope( +.\" Dwarf_Debug dbg, +.\" Dwarf_Addr pc, +.\" Dwarf_Error *error)\fP +.\".DE +.\"The function +.\"\f(CWdwarf_pcscope()\fP returns the \f(CWDwarf_Die\fP descriptor for +.\"the debugging information entry that represents the innermost enclosing +.\"scope containing \f(CWpc\fP, or \fINULL\fP if no entry exists or an +.\"error occurred. Debugging information entries that represent a \fIscope\fP +.\"are those containing a low pc attribute and either a high pc or byte +.\"size attribute that delineates a range. For example: a debugging information +.\"entry for a lexical block is considered one having a scope whereas a +.\"debugging information entry for a label is not. This function is +.\"currently unimplemented. +.\"#endif + + +.H 2 "Debugging Information Entry Query Operations" +These queries return specific information about debugging information +entries or a descriptor that can be used on subsequent queries when +given a \f(CWDwarf_Die\fP descriptor. Note that some operations are +specific to debugging information entries that are represented by a +\f(CWDwarf_Die\fP descriptor of a specific type. +For example, not all +debugging information entries contain an attribute having a name, so +consequently, a call to \f(CWdwarf_diename()\fP using a \f(CWDwarf_Die\fP +descriptor that does not have a name attribute will return +\f(CWDW_DLV_NO_ENTRY\fP. +This is not an error, i.e. calling a function that needs a specific +attribute is not an error for a die that does not contain that specific +attribute. +.P +There are several methods that can be used to obtain the value of an +attribute in a given die: +.AL 1 +.LI +Call \f(CWdwarf_hasattr()\fP to determine if the debugging information +entry has the attribute of interest prior to issuing the query for +information about the attribute. + +.LI +Supply an \f(CWerror\fP argument, and check its value after the call to +a query indicates an unsuccessful return, to determine the nature of the +problem. The \f(CWerror\fP argument will indicate whether an error occurred, +or the specific attribute needed was missing in that die. + +.LI +Arrange to have an error handling function invoked upon detection of an +error (see \f(CWdwarf_init()\fP). + +.LI +Call \f(CWdwarf_attrlist()\fP and iterate through the returned list of +attributes, dealing with each one as appropriate. +.LE +.P + +.H 3 "dwarf_tag()" +.DS +\f(CWint dwarf_tag( + Dwarf_Die die, + Dwarf_Half *tagval, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_tag()\fP returns the \fItag\fP of \f(CWdie\fP +thru the pointer \f(CWtagval\fP if it succeeds. +It returns \f(CWDW_DLV_OK\fP if it succeeds. +It returns \f(CWDW_DLV_ERROR\fP on error. + +.H 3 "dwarf_dieoffset()" +.DS +\f(CWint dwarf_dieoffset( + Dwarf_Die die, + Dwarf_Off * return_offset, + Dwarf_Error *error)\fP +.DE +When it succeeds, +the function \f(CWdwarf_dieoffset()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP +to the position of \f(CWdie\fP +in the section containing debugging information entries +(the \f(CWreturn_offset\fP is a section-relative offset). +In other words, +it sets \f(CWreturn_offset\fP +to the offset of the start of the debugging information entry +described by \f(CWdie\fP in the section containing die's i.e .debug_info. +It returns \f(CWDW_DLV_ERROR\fP on error. + +.H 3 "dwarf_die_CU_offset()" +.DS +\f(CWint dwarf_die_CU_offset( + Dwarf_Die die, + Dwarf_Off *return_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_die_CU_offset()\fP is similar to +\f(CWdwarf_dieoffset()\fP, except that it puts the offset of the DIE +represented by the \f(CWDwarf_Die\fP \f(CWdie\fP, from the +start of the compilation-unit that it belongs to rather than the start +of .debug_info (the \f(CWreturn_offset\fP is a CU-relative offset). + + +.H 3 "dwarf_diename()" +.DS +\f(CWint dwarf_diename( + Dwarf_Die die, + char ** return_name, + Dwarf_Error *error)\fP +.DE +When it succeeds, +the function \f(CWdwarf_diename()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP +to +a pointer to a +null-terminated string of characters that represents the name +attribute of \f(CWdie\fP. +It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have a name attribute. +It returns \f(CWDW_DLV_ERROR\fP if +an error occurred. +The storage pointed to by a successful return of +\f(CWdwarf_diename()\fP should be free'd using the allocation type +\f(CWDW_DLA_STRING\fP when no longer of interest (see +\f(CWdwarf_dealloc()\fP). + +.H 3 "dwarf_attrlist()" +.DS +\f(CWint dwarf_attrlist( + Dwarf_Die die, + Dwarf_Attribute** attrbuf, + Dwarf_Signed *attrcount, + Dwarf_Error *error)\fP +.DE +When it returns \f(CWDW_DLV_OK\fP, +the function \f(CWdwarf_attrlist()\fP sets \f(CWattrbuf\fP to point +to an array of \f(CWDwarf_Attribute\fP descriptors corresponding to +each of the attributes in die, and returns the number of elements in +the array thru \f(CWattrcount\fP. +\f(CWDW_DLV_NO_ENTRY\fP is returned if the count is zero (no +\f(CWattrbuf\fP is allocated in this case). +\f(CWDW_DLV_ERROR\fP is returned on error. +On a successful return from \f(CWdwarf_attrlist()\fP, each of the +\f(CWDwarf_Attribute\fP descriptors should be individually free'd using +\f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ATTR\fP, +followed by free-ing the list pointed to by \f(CW*attrbuf\fP using +\f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_LIST\fP, +when no longer of interest (see \f(CWdwarf_dealloc()\fP). + +Freeing the attrlist: +.in +2 +.DS +\f(CWDwarf_Unsigned atcnt; +Dwarf_Attribute *atlist; +int errv; + +errv = dwarf_attrlist(somedie, &atlist,&atcnt, &error); +if (errv == DW_DLV_OK) { + + for (i = 0; i < atcnt; ++i) { + /* use atlist[i] */ + dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR); + } + dwarf_dealloc(dbg, atlist, DW_DLA_LIST); +}\fP +.DE +.in -2 +.P +.H 3 "dwarf_hasattr()" +.DS +\f(CWint dwarf_hasattr( + Dwarf_Die die, + Dwarf_Half attr, + Dwarf_Bool *return_bool, + Dwarf_Error *error)\fP +.DE +When it succeeds, the +function \f(CWdwarf_hasattr()\fP returns \f(CWDW_DLV_OK\fP +and sets \f(CW*return_bool\fP to \fInon-zero\fP if +\f(CWdie\fP has the attribute \f(CWattr\fP and \fIzero\fP otherwise. +If it fails, it returns \f(CWDW_DLV_ERROR\fP. + +.H 3 "dwarf_attr()" +.DS +\f(CWint dwarf_attr( + Dwarf_Die die, + Dwarf_Half attr, + Dwarf_Attribute *return_attr, + Dwarf_Error *error)\fP +.DE +When it returns \f(CWDW_DLV_OK\fP, +the function \f(CWdwarf_attr()\fP +sets +\f(CW*return_attr\fP to the \f(CWDwarf_Attribute\fP +descriptor of \f(CWdie\fP having the attribute \f(CWattr\fP. +It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWattr\fP is not contained +in \f(CWdie\fP. +It returns \f(CWDW_DLV_ERROR\fP if an error occurred. + +.\"#if 0 +.\".DS +.\"\f(CWDwarf_Locdesc* dwarf_stringlen( +.\" Dwarf_Die die, +.\" Dwarf_Error *error)\fP +.\".DE +.\"The function \f(CWdwarf_stringlen()\fP returns a pointer to a +.\"\f(CWDwarf_Locdesc\fP with one Locdesc entry that when evaluated, +.\"yields the length of the string represented by \f(CWdie\fP. It +.\"returns \f(CWNULL\fP if \f(CWdie\fP does not contain a string length +.\"attribute or the string length attribute is not a location-description +.\"or an error occurred. The address range of the list is set to 0 thru +.\"the highest possible address if a loclist pointer is returned. The +.\"storage pointed to by a successful return of \f(CWdwarf_stringlen()\fP +.\"should be free'd when no longer of interest (see \f(CWdwarf_dealloc()\fP). +.\"This function is currently unimplemented. +.\"#endif + +.\"#if 0 +.\".DS +.\"\f(CWDwarf_Signed dwarf_subscrcnt( +.\" Dwarf_Die die, +.\" Dwarf_Error *error)\fP +.\".DE +.\"The function \f(CWdwarf_subscrcnt()\fP returns the number of subscript +.\"die's that are owned by the array type represented by \f(CWdie\fP. It +.\"returns \f(CWDW_DLV_NOCOUNT\fP on error. This function is currently +.\"unimplemented. +.\" +.\".DS +.\"\f(CWDwarf_Die dwarf_nthsubscr( +.\" Dwarf_Die die, +.\" Dwarf_Unsigned ssndx, +.\" Dwarf_Error *error)\fP +.\".DE +.\"The function \f(CWdwarf_nthsubscr()\fP returns a \f(CWDwarf_Die\fP +.\"descriptor that describes the \f(CWssndx\fP subscript of the array +.\"type debugging information entry represented by \f(CWdie\fP, where +.\"\fI1\fP is the first member. It returns \fINULL\fP if \f(CWdie\fP +.\"does not have an \f(CWssndx\fP subscript, or an error occurred. +.\"This function is currently unimplemented. +.\"#endif + +.H 3 "dwarf_lowpc()" +.DS +\f(CWint dwarf_lowpc( + Dwarf_Die die, + Dwarf_Addr * return_lowpc, + Dwarf_Error * error)\fP +.DE +The function \f(CWdwarf_lowpc()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_lowpc\fP +to the low program counter +value associated with the \f(CWdie\fP descriptor if \f(CWdie\fP +represents a debugging information entry with this attribute. +It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have this +attribute. +It returns \f(CWDW_DLV_ERROR\fP if an error occurred. + +.H 3 "dwarf_highpc()" +.DS +\f(CWint dwarf_highpc( + Dwarf_Die die, + Dwarf_Addr * return_highpc, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_highpc()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_highpc\fP +the high program counter +value associated with the \f(CWdie\fP descriptor if \f(CWdie\fP +represents a debugging information entry with this attribute. +It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have this +attribute. +It returns \f(CWDW_DLV_ERROR\fP if an error occurred. + +.H 3 "dwarf_bytesize()" +.DS +\f(CWDwarf_Signed dwarf_bytesize( + Dwarf_Die die, + Dwarf_Unsigned *return_size, + Dwarf_Error *error)\fP +.DE +When it succeeds, +\f(CWdwarf_bytesize()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_size\fP +to the number of bytes +needed to contain an instance of the aggregate debugging information +entry represented by \f(CWdie\fP. +It returns \f(CWDW_DLV_NO_ENTRY\fP if +\f(CWdie\fP does not contain the byte size attribute \f(CWDW_AT_byte_size\fP. +It returns \f(CWDW_DLV_ERROR\fP if +an error occurred. + +.\"#if 0 +.\".DS +.\"\f(CWDwarf_Bool dwarf_isbitfield( +.\" Dwarf_Die die, +.\" Dwarf_Error *error)\fP +.\".DE +.\"The function \f(CWdwarf_isbitfield()\fP returns \fInon-zero\fP if +.\"\f(CWdie\fP is a descriptor for a debugging information entry that +.\"represents a bit field member. It returns \fIzero\fP if \f(CWdie\fP +.\"is not associated with a bit field member. This function is currently +.\"unimplemented. +.\"#endif + +.H 3 "dwarf_bitsize()" +.DS +\f(CWint dwarf_bitsize( + Dwarf_Die die, + Dwarf_Unsigned *return_size, + Dwarf_Error *error)\fP +.DE +When it succeeds, +\f(CWdwarf_bitsize()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_size\fP +to the number of +bits +occupied by the bit field value that is an attribute of the given +die. +It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not +contain the bit size attribute \f(CWDW_AT_bit_size\fP. +It returns \f(CWDW_DLV_ERROR\fP if +an error occurred. + +.H 3 "dwarf_bitoffset()" +.DS +\f(CWint dwarf_bitoffset( + Dwarf_Die die, + Dwarf_Unsigned *return_size, + Dwarf_Error *error)\fP +.DE +When it succeeds, +\f(CWdwarf_bitoffset()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_size\fP +to the number of bits +to the left of the most significant bit of the bit field value. +This bit offset is not necessarily the net bit offset within the +structure or class , since \f(CWDW_AT_data_member_location\fP +may give a byte offset to this \f(CWDIE\fP and the bit offset +returned through the pointer +does not include the bits in the byte offset. +It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not contain the +bit offset attribute \f(CWDW_AT_bit_offset\fP. +It returns \f(CWDW_DLV_ERROR\fP if +an error occurred. + +.H 3 "dwarf_srclang()" +.DS +\f(CWint dwarf_srclang( + Dwarf_Die die, + Dwarf_Unsigned *return_lang, + Dwarf_Error *error)\fP +.DE +When it succeeds, +\f(CWdwarf_srclang()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_lang\fP +to +a code indicating the +source language of the compilation unit represented by the descriptor +\f(CWdie\fP. +It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not +represent a source file debugging information entry (i.e. contain the +attribute \f(CWDW_AT_language\fP). +It returns \f(CWDW_DLV_ERROR\fP if +an error occurred. + +.H 3 "dwarf_arrayorder()" +.DS +\f(CWint dwarf_arrayorder( + Dwarf_Die die, + Dwarf_Unsigned *return_order, + Dwarf_Error *error)\fP +.DE +When it succeeds, +\f(CWdwarf_arrayorder()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_order\fP +a code indicating +the ordering of the array represented by the descriptor \f(CWdie\fP. +It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not contain the +array order attribute \f(CWDW_AT_ordering\fP. +It returns \f(CWDW_DLV_ERROR\fP if +an error occurred. + +.H 2 "Attribute Form Queries" +Based on the attribute's form, these operations are concerned with +returning uninterpreted attribute data. Since it is not always +obvious from the return value of these functions if an error occurred, +one should always supply an \f(CWerror\fP parameter or have arranged +to have an error handling function invoked (see \f(CWdwarf_init()\fP) +to determine the validity of the returned value and the nature of any +errors that may have occurred. + +A \f(CWDwarf_Attribute\fP descriptor describes an attribute of a +specific die. Thus, each \f(CWDwarf_Attribute\fP descriptor is +implicitly associated with a specific die. + +.H 3 "dwarf_hasform()" +.DS +\f(CWnt dwarf_hasform( + Dwarf_Attribute attr, + Dwarf_Half form, + Dwarf_Bool *return_hasform, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_hasform()\fP returns +\f(CWDW_DLV_OK\fP and and puts a +\fInon-zero\fP + value in the +\f(CW*return_hasform\fP boolean if the +attribute represented by the \f(CWDwarf_Attribute\fP descriptor +\f(CWattr\fP has the attribute form \f(CWform\fP. +If the attribute does not have that form \fIzero\fP +is put into \f(CW*return_hasform\fP. +\f(CWDW_DLV_ERROR\fP is returned on error. + +.H 3 "dwarf_whatform()" +.DS +\f(CWint dwarf_whatform( + Dwarf_Attribute attr, + Dwarf_Half *return_form, + Dwarf_Error *error)\fP +.DE +When it succeeds, +\f(CWdwarf_whatform()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_form\fP +to the attribute form code of +the attribute represented by the \f(CWDwarf_Attribute\fP descriptor +\f(CWattr\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +An attribute using DW_FORM_indirect effectively has two forms. +This function returns the 'final' form for \f(CWDW_FORM_indirect\fP, +not the \f(CWDW_FORM_indirect\fP itself. This function is +what most applications will want to call. + +.H 3 "dwarf_whatform_direct()" +.DS +\f(CWint dwarf_whatform_direct( + Dwarf_Attribute attr, + Dwarf_Half *return_form, + Dwarf_Error *error)\fP +.DE +When it succeeds, +\f(CWdwarf_whatform_direct()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_form\fP +to the attribute form code of +the attribute represented by the \f(CWDwarf_Attribute\fP descriptor +\f(CWattr\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +An attribute using \f(CWDW_FORM_indirect\fP effectively has two forms. +This returns the form 'directly' in the initial form field. +So when the form field is \f(CWDW_FORM_indirect\fP +this call returns the \f(CWDW_FORM_indirect\fP form, +which is sometimes useful for dump utilities. + +.H 3 "dwarf_whatattr()" +.DS +\f(CWint dwarf_whatattr( + Dwarf_Attribute attr, + Dwarf_Half *return_attr, + Dwarf_Error *error)\fP +.DE +When it succeeds, +\f(CWdwarf_whatattr()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_attr\fP +to the attribute code +represented by the \f(CWDwarf_Attribute\fP descriptor \f(CWattr\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. + +.H 3 "dwarf_formref()" +.DS +\f(CWint dwarf_formref( + Dwarf_Attribute attr, + Dwarf_Off *return_offset, + Dwarf_Error *error)\fP +.DE +When it succeeds, +\f(CWdwarf_formref()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP +to the CU-relative offset +represented by the descriptor \f(CWattr\fP if the form of the attribute +belongs to the \f(CWREFERENCE\fP class. +\f(CWattr\fP must be a CU-local reference, +not form \f(CWDW_FORM_ref_addr\fP. +It is an error for the form to +not belong to this class or to be form \f(CWDW_FORM_ref_addr\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +See also \f(CWdwarf_global_formref\fP below. + +.H 3 "dwarf_global_formref()" +.DS +\f(CWint dwarf_global_formref( + Dwarf_Attribute attr, + Dwarf_Off *return_offset, + Dwarf_Error *error)\fP +.DE +When it succeeds, +\f(CWdwarf_global_formref()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP +to the .debug_info-section-relative offset +represented by the descriptor \f(CWattr\fP if the form of the attribute +belongs to the \f(CWREFERENCE\fP class. +\f(CWattr\fP can be any legal +\f(CWREFERENCE\fP class form including \f(CWDW_FORM_ref_addr\fP. +It is an error for the form to +not belong to this class. +It returns \f(CWDW_DLV_ERROR\fP on error. +See also \f(CWdwarf_formref\fP above. + +.H 3 "dwarf_formaddr()" +.DS +\f(CWint dwarf_formaddr( + Dwarf_Attribute attr, + Dwarf_Addr * return_addr, + Dwarf_Error *error)\fP +.DE +When it succeeds, +\f(CWdwarf_formaddr()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_addr\fP +to +the address +represented by the descriptor \f(CWattr\fP if the form of the attribute +belongs to the \f(CWADDRESS\fP class. +It is an error for the form to +not belong to this class. +It returns \f(CWDW_DLV_ERROR\fP on error. + +.H 3 "dwarf_formflag()" +.DS +\f(CWint dwarf_formflag( + Dwarf_Attribute attr, + Dwarf_Bool * return_bool, + Dwarf_Error *error)\fP +.DE +When it succeeds, +\f(CWdwarf_formflag()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP +\f(CW1\fP (i.e. true) (if the attribute has a non-zero value) +or \f(CW0\fP (i.e. false) (if the attribute has a zero value). +It returns \f(CWDW_DLV_ERROR\fP on error or if the \f(CWattr\fP +does not have form flag. + +.H 3 "dwarf_formudata()" +.DS +\f(CWint dwarf_formudata( + Dwarf_Attribute attr, + Dwarf_Unsigned * return_uvalue, + Dwarf_Error * error)\fP +.DE +The function +\f(CWdwarf_formudata()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_uvalue\fP +to +the \f(CWDwarf_Unsigned\fP +value of the attribute represented by the descriptor \f(CWattr\fP if the +form of the attribute belongs to the \f(CWCONSTANT\fP class. +It is an +error for the form to not belong to this class. +It returns \f(CWDW_DLV_ERROR\fP on error. + +.H 3 "dwarf_formsdata()" +.DS +\f(CWint dwarf_formsdata( + Dwarf_Attribute attr, + Dwarf_Signed * return_svalue, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_formsdata()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_svalue\fP +to +the \f(CWDwarf_Signed\fP +value of the attribute represented by the descriptor \f(CWattr\fP if the +form of the attribute belongs to the \f(CWCONSTANT\fP class. +It is an +error for the form to not belong to this class. +If the size of the data +attribute referenced is smaller than the size of the \f(CWDwarf_Signed\fP +type, its value is sign extended. +It returns \f(CWDW_DLV_ERROR\fP on error. + +.H 3 "dwarf_formblock()" +.DS +\f(CWint dwarf_formblock( + Dwarf_Attribute attr, + Dwarf_Block ** return_block, + Dwarf_Error * error)\fP +.DE +The function \f(CWdwarf_formblock()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_block\fP +to +a pointer to a +\f(CWDwarf_Block\fP structure containing the value of the attribute +represented by the descriptor \f(CWattr\fP if the form of the +attribute belongs to the \f(CWBLOCK\fP class. +It is an error +for the form to not belong to this class. +The storage pointed +to by a successful return of \f(CWdwarf_formblock()\fP should +be free'd using the allocation type \f(CWDW_DLA_BLOCK\fP, when +no longer of interest (see \f(CWdwarf_dealloc()\fP). +It returns +\f(CWDW_DLV_ERROR\fP on error. + +.H 3 "dwarf_formstring()" + +.DS +\f(CWint dwarf_formstring( + Dwarf_Attribute attr, + char ** return_string, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_formstring()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_string\fP +to +a pointer to a +null-terminated string containing the value of the attribute +represented by the descriptor \f(CWattr\fP if the form of the +attribute belongs to the \f(CWSTRING\fP class. +It is an error +for the form to not belong to this class. +The storage pointed +to by a successful return of \f(CWdwarf_formstring()\fP +should not be free'd. The pointer points into +existing DWARF memory and the pointer becomes stale/invalid +after a call to \f(CWdwarf_finish\fP. +\f(CWdwarf_formstring()\fP returns \f(CWDW_DLV_ERROR\fP on error. + +.H 4 "dwarf_loclist_n()" +.DS +\f(CWint dwarf_loclist_n( + Dwarf_Attribute attr, + Dwarf_Locdesc ***llbuf, + Dwarf_Signed *listlen, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_loclist_n()\fP sets \f(CW*llbuf\fP to point to +an array of \f(CWDwarf_Locdesc\fP pointers corresponding to each of +the location expressions in a location list, and sets +\f(CW*listlen\fP to the number +of elements in the array and +returns \f(CWDW_DLV_OK\fP if the attribute is +appropriate. +.P +This is the preferred function for Dwarf_Locdesc as +it is the interface allowing access to an entire +loclist. (use of \f(CWdwarf_loclist_n()\fP is +suggested as the better interface, though +\f(CWdwarf_loclist()\fP is still +supported.) +.P +If the attribute is a reference to a location list +(DW_FORM_data4 or DW_FORM_data8) +the location list entries are used to fill +in all the fields of the \f(CWDwarf_Locdesc\fP(s) returned. +.P +If the attribute is a location description +(DW_FORM_block2 or DW_FORM_block4) +then some of the \f(CWDwarf_Locdesc\fP values of the single +\f(CWDwarf_Locdesc\fP record are set to 'sensible' +but arbitrary values. Specifically, ld_lopc is set to 0 and +ld_hipc is set to all-bits-on. And \f(CW*listlen\fP is set to 1. +.P +It returns \f(CWDW_DLV_ERROR\fP on error. +\f(CWdwarf_loclist_n()\fP works on \f(CWDW_AT_location\fP, +\f(CWDW_AT_data_member_location\fP, \f(CWDW_AT_vtable_elem_location\fP, +\f(CWDW_AT_string_length\fP, \f(CWDW_AT_use_location\fP, and +\f(CWDW_AT_return_addr\fP attributes. +.P +Storage allocated by a successful call of \f(CWdwarf_loclist_n()\fP should +be deallocated when no longer of interest (see \f(CWdwarf_dealloc()\fP). +The block of \f(CWDwarf_Loc\fP structs pointed to by the \f(CWld_s\fP +field of each \f(CWDwarf_Locdesc\fP structure +should be deallocated with the allocation type +\f(CWDW_DLA_LOC_BLOCK\fP. +and the \f(CWllbuf[]\fP space pointed to should be deallocated with +allocation type \f(CWDW_DLA_LOCDESC\fP. +This should be followed by deallocation of the \f(CWllbuf\fP +using the allocation type \f(CWDW_DLA_LIST\fP. +.in +2 +.DS +\f(CWDwarf_Signed lcnt; +Dwarf_Locdesc **llbuf; +int lres; + +lres = dwarf_loclist_n(someattr, &llbuf,&lcnt &error); +if (lres == DW_DLV_OK) { + for (i = 0; i < lcnt; ++i) { + /* use llbuf[i] */ + + dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK); + dwarf_dealloc(dbg,llbuf[i], DW_DLA_LOCDESC); + } + dwarf_dealloc(dbg, llbuf, DW_DLA_LIST); +}\fP +.DE +.in -2 +.P + +.H 4 "dwarf_loclist()" +.DS +\f(CWint dwarf_loclist( + Dwarf_Attribute attr, + Dwarf_Locdesc **llbuf, + Dwarf_Signed *listlen, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_loclist()\fP sets \f(CW*llbuf\fP to point to +a \f(CWDwarf_Locdesc\fP pointer for the single location expression +it can return. +It sets +\f(CW*listlen\fP to 1. +and returns \f(CWDW_DLV_OK\fP +if the attribute is +appropriate. +.P +It is less flexible than \f(CWdwarf_loclist_n()\fP in that +\f(CWdwarf_loclist()\fP can handle a maximum of one +location expression, not a full location list. +If a location-list is present it returns only +the first location-list entry location description. +Use \f(CWdwarf_loclist_n()\fP instead. +.P +It returns \f(CWDW_DLV_ERROR\fP on error. +\f(CWdwarf_loclist()\fP works on \f(CWDW_AT_location\fP, +\f(CWDW_AT_data_member_location\fP, \f(CWDW_AT_vtable_elem_location\fP, +\f(CWDW_AT_string_length\fP, \f(CWDW_AT_use_location\fP, and +\f(CWDW_AT_return_addr\fP attributes. +.P +Storage allocated by a successful call of \f(CWdwarf_loclist()\fP should +be deallocated when no longer of interest (see \f(CWdwarf_dealloc()\fP). +The block of \f(CWDwarf_Loc\fP structs pointed to by the \f(CWld_s\fP +field of each \f(CWDwarf_Locdesc\fP structure +should be deallocated with the allocation type \f(CWDW_DLA_LOC_BLOCK\fP. +This should be followed by deallocation of the \f(CWllbuf\fP +using the allocation type \f(CWDW_DLA_LOCDESC\fP. +.in +2 +.DS +\f(CWDwarf_Signed lcnt; +Dwarf_Locdesc *llbuf; +int lres; + +lres = dwarf_loclist(someattr, &llbuf,&lcnt,&error); +if (lres == DW_DLV_OK) { + /* lcnt is always 1, (and has always been 1) */ */ + + /* Use llbuf here. */ + + + dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK); + dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC); +/* Earlier version. +* for (i = 0; i < lcnt; ++i) { +* /* use llbuf[i] */ +* +* /* Deallocate Dwarf_Loc block of llbuf[i] */ +* dwarf_dealloc(dbg, llbuf[i].ld_s, DW_DLA_LOC_BLOCK); +* } +* dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC); +*/ + +}\fP +.DE +.in -2 +.P + +.H 4 "dwarf_loclist_from_expr()" +.DS +\f(CWint dwarf_loclist_from_expr( + Dwarf_Ptr bytes_in, + Dwarf_Unsigned bytes_len, + Dwarf_Locdesc **llbuf, + Dwarf_Signed *listlen, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_loclist_from_expr()\fP sets \f(CW*llbuf\fP to point to +a \f(CWDwarf_Locdesc\fP pointer for the single location expression +which is pointed to by \f(CW*bytes_in\fP (whose length is +\f(CW*bytes_len\fP). +It sets +\f(CW*listlen\fP to 1. +and returns \f(CWDW_DLV_OK\fP +if decoding is successful. +Some sources of bytes of expressions are dwarf expressions +in frame operations like \f(CWDW_CFA_def_cfa_expression\fP, +\f(CWDW_CFA_expression\fP, and \f(CWDW_CFA_val_expression\fP. +.P +It returns \f(CWDW_DLV_ERROR\fP on error. +.P +Storage allocated by a successful call of \f(CWdwarf_loclist_from_expr()\fP should +be deallocated when no longer of interest (see \f(CWdwarf_dealloc()\fP). +The block of \f(CWDwarf_Loc\fP structs pointed to by the \f(CWld_s\fP +field of each \f(CWDwarf_Locdesc\fP structure +should be deallocated with the allocation type \f(CWDW_DLA_LOC_BLOCK\fP. +This should be followed by deallocation of the \f(CWllbuf\fP +using the allocation type \f(CWDW_DLA_LOCDESC\fP. +.in +2 +.DS +\f(CWDwarf_Signed lcnt; +Dwarf_Locdesc *llbuf; +int lres; +/* Example with an empty buffer here. */ +Dwarf_Ptr data = ""; +Dwarf_Unsigned len = 0; + +lres = dwarf_loclist_from_expr(data,len, &llbuf,&lcnt, &error); +if (lres == DW_DLV_OK) { + /* lcnt is always 1 */ + + /* Use llbuf here.*/ + + dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK); + dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC); + +}\fP +.DE +.in -2 +.P + + +.P +.H 2 "Line Number Operations" +These functions are concerned with accessing line number entries, +mapping debugging information entry objects to their corresponding +source lines, and providing a mechanism for obtaining information +about line number entries. Although, the interface talks of "lines" +what is really meant is "statements". In case there is more than +one statement on the same line, there will be at least one descriptor +per statement, all with the same line number. If column number is +also being represented they will have the column numbers of the start +of the statements also represented. +.P +There can also be more than one Dwarf_Line per statement. +For example, if a file is preprocessed by a language translator, +this could result in translator output showing 2 or more sets of line +numbers per translated line of output. + +.H 3 "Get A Set of Lines" +The function returns information about every source line for a +particular compilation-unit. +The compilation-unit is specified +by the corresponding die. +.H 4 "dwarf_srclines()" +.DS +\f(CWint dwarf_srclines( + Dwarf_Die die, + Dwarf_Line **linebuf, + Dwarf_Signed *linecount, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_srclines()\fP places all line number descriptors +for a single compilation unit into a single block, sets \f(CW*linebuf\fP +to point to that block, +sets \f(CW*linecount\fP to the number of descriptors in this block +and returns \f(CWDW_DLV_OK\fP. +The compilation-unit is indicated by the given \f(CWdie\fP which must be +a compilation-unit die. +It returns \f(CWDW_DLV_ERROR\fP on error. +On +successful return, line number information +should be free'd using \f(CWdwarf_srclines_dealloc()\fP +when no longer of interest. +.P +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Line *linebuf; +int sres; + +sres = dwarf_srclines(somedie, &linebuf,&cnt, &error); +if (sres == DW_DLV_OK) { + for (i = 0; i < cnt; ++i) { + /* use linebuf[i] */ + } + dwarf_srclines_dealloc(dbg, linebuf, cnt); +}\fP +.DE + +.in -2 +.P +The following dealloc code (the only documented method before July 2005) +still works, but does not completely free all data allocated. +The \f(CWdwarf_srclines_dealloc()\fP routine was created +to fix the problem of incomplete deallocation. +.P +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Line *linebuf; +int sres; + +sres = dwarf_srclines(somedie, &linebuf,&cnt, &error); +if (sres == DW_DLV_OK) { + for (i = 0; i < cnt; ++i) { + /* use linebuf[i] */ + dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE); + } + dwarf_dealloc(dbg, linebuf, DW_DLA_LIST); +}\fP +.DE +.in -2 + +.H 3 "Get the set of Source File Names" + +The function returns the names of the source files that have contributed +to the compilation-unit represented by the given DIE. Only the source +files named in the statement program prologue are returned. + + +.DS +\f(CWint dwarf_srcfiles( + Dwarf_Die die, + char ***srcfiles, + Dwarf_Signed *srccount, + Dwarf_Error *error)\fP +.DE +When it succeeds +\f(CWdwarf_srcfiles()\fP returns +\f(CWDW_DLV_OK\fP +and +puts +the number of source +files named in the statement program prologue indicated by the given +\f(CWdie\fP +into \f(CW*srccount\fP. +Source files defined in the statement program are ignored. +The given \f(CWdie\fP should have the tag \f(CWDW_TAG_compile_unit\fP. +The location pointed to by \f(CWsrcfiles\fP is set to point to a list +of pointers to null-terminated strings that name the source +files. +On a successful return from this function, each of the +strings returned should be individually free'd using \f(CWdwarf_dealloc()\fP +with the allocation type \f(CWDW_DLA_STRING\fP when no longer of +interest. +This should be followed by free-ing the list using +\f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_LIST\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It returns \f(CWDW_DLV_NO_ENTRY\fP +if there is no +corresponding statement program (i.e., if there is no line information). +.in +2 +.DS +\f(CWDwarf_Signed cnt; +char **srcfiles; +int res; + +res = dwarf_srcfiles(somedie, &srcfiles,&cnt &error); +if (res == DW_DLV_OK) { + + for (i = 0; i < cnt; ++i) { + /* use srcfiles[i] */ + dwarf_dealloc(dbg, srcfiles[i], DW_DLA_STRING); + } + dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST); +}\fP +.DE +.in -2 +.H 3 "Get information about a Single Table Line" +The following functions can be used on the \f(CWDwarf_Line\fP descriptors +returned by \f(CWdwarf_srclines()\fP to obtain information about the +source lines. + +.H 4 "dwarf_linebeginstatement()" +.DS +\f(CWint dwarf_linebeginstatement( + Dwarf_Line line, + Dwarf_Bool *return_bool, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_linebeginstatement()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP +to +\fInon-zero\fP +(if \f(CWline\fP represents a line number entry that is marked as +beginning a statement). +or +\fIzero\fP ((if \f(CWline\fP represents a line number entry +that is not marked as beginning a statement). +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.P +.H 4 "dwarf_lineendsequence()" +.DS +\f(CWint dwarf_lineendsequence( + Dwarf_Line line, + Dwarf_Bool *return_bool, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_lineendsequence()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP +\fInon-zero\fP +(in which case +\f(CWline\fP represents a line number entry that is marked as +ending a text sequence) +or +\fIzero\fP (in which case +\f(CWline\fP represents a line number entry +that is not marked as ending a text sequence). +A line number entry that is marked as +ending a text sequence is an entry with an address +one beyond the highest address used by the current +sequence of line table entries (that is, the table entry is +a DW_LNE_end_sequence entry (see the DWARF specification)). +.P +The function \f(CWdwarf_lineendsequence()\fP +returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.P +.H 4 "dwarf_lineno()" +.DS +\f(CWint dwarf_lineno( + Dwarf_Line line, + Dwarf_Unsigned * returned_lineno, + Dwarf_Error * error)\fP +.DE +The function \f(CWdwarf_lineno()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_lineno\fP to +the source statement line +number corresponding to the descriptor \f(CWline\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.P +.H 4 "dwarf_line_srcfileno()" +.DS +\f(CWint dwarf_line_srcfileno( + Dwarf_Line line, + Dwarf_Unsigned * returned_fileno, + Dwarf_Error * error)\fP +.DE +The function \f(CWdwarf_line_srcfileno()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*returned_fileno\fP to +the source statement line +number corresponding to the descriptor \f(CWfile number\fP. +When the number returned thru \f(CW*returned_fileno\fP is zero it means +the file name is unknown (see the DWARF2/3 line table specification). +When the number returned thru \f(CW*returned_fileno\fP is non-zero +it is a file number: +subtract 1 from this file number +to get an +index into the array of strings returned by \f(CWdwarf_srcfiles()\fP +(verify the resulting index is in range for the array of strings +before indexing into the array of strings). +The file number may exceed the size of +the array of strings returned by \f(CWdwarf_srcfiles()\fP +because \f(CWdwarf_srcfiles()\fP does not return files names defined with +the \f(CWDW_DLE_define_file\fP operator. +The function \f(CWdwarf_line_srcfileno()\fP returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.P +.H 4 "dwarf_lineaddr()" +.DS +\f(CWint dwarf_lineaddr( + Dwarf_Line line, + Dwarf_Addr *return_lineaddr, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_lineaddr()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_lineaddr\fP to +the address associated +with the descriptor \f(CWline\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.P +.H 4 "dwarf_lineoff()" +.DS +\f(CWint dwarf_lineoff( + Dwarf_Line line, + Dwarf_Signed * return_lineoff, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_lineoff()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_lineoff\fP to +the column number at which +the statement represented by \f(CWline\fP begins. +It sets \f(CWreturn_lineoff\fP to \fI-1\fP +if the column number of the statement is not represented +(meaning the producer library call was given zero +as the column number). +.P +On error it returns \f(CWDW_DLV_ERROR\fP. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 4 "dwarf_linesrc()" +.DS +\f(CWint dwarf_linesrc( + Dwarf_Line line, + char ** return_linesrc, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_linesrc()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_linesrc\fP to +a pointer to a +null-terminated string of characters that represents the name of the +source-file where \f(CWline\fP occurs. +It returns \f(CWDW_DLV_ERROR\fP on +error. +.P +If the applicable file name in the line table Statement Program Prolog +does not start with a '/' character +the string in \f(CWDW_AT_comp_dir\fP (if applicable and present) +or the applicable +directory name from the line Statement Program Prolog +is prepended to the +file name in the line table Statement Program Prolog +to make a full path. +.P +The storage pointed to by a successful return of +\f(CWdwarf_linesrc()\fP should be free'd using \f(CWdwarf_dealloc()\fP with +the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 4 "dwarf_lineblock()" +.DS +\f(CWint dwarf_lineblock( + Dwarf_Line line, + Dwarf_Bool *return_bool, + Dwarf_Error *error)\fP +.DE +The function +\f(CWdwarf_lineblock()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_linesrc\fP to +non-zero (i.e. true)(if the line is marked as +beginning a basic block) +or zero (i.e. false) (if the line is marked as not +beginning a basic block). +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.\"#if 0 +.\".H 3 "Finding a Line Given A PC value" +.\"This is a 'higher level' (High-level) interface to line information. +.\" +.\".DS +.\"\f(CWint dwarf_pclines( +.\" Dwarf_Debug dbg, +.\" Dwarf_Addr pc, +.\" Dwarf_Line **linebuf, +.\" Dwarf_Signed slide, +.\" Dwarf_Signed *linecount, +.\" Dwarf_Error *error)\fP +.\".DE +.\"The function \f(CWdwarf_pclines()\fP places all line number descriptors +.\"that correspond to the value of \f(CWpc\fP into a single block and sets +.\"\f(CWlinebuf\fP to point to that block. A count of the number of +.\"\f(CWDwarf_Line\fP descriptors that are in this block is returned. For +.\"most cases, the count returned will be \fIone\fP, though it may be higher +.\"if optimizations such as common subexpression elimination result in multiple +.\"line number entries for a given value of \f(CWpc\fP. The \f(CWslide\fP +.\"argument specifies the direction to search for the nearest line number +.\"entry in the event that there is no line number entry that contains an +.\"exact match for \f(CWpc\fP. This argument may be one of: +.\"\f(CWDLS_BACKWARD\fP, \f(CWDLS_NOSLIDE\fP, \f(CWDLS_FORWARD\fP. +.\"\f(CWDW_DLV_NOCOUNT\fP is returned on error. On successful return, each +.\"line information structure pointed to by an entry in the block should be +.\"free'd using \f(CWdwarf_dealloc()\fP with the allocation type +.\"\f(CWDW_DLA_LINE\fP when no longer of interest. The block itself should +.\"be free'd using \f(CWdwarf_dealloc()\fP with the allocation type +.\"\f(CWDW_DLA_LIST\fP when no longer of interest. +.\"#endif + +.H 2 "Global Name Space Operations" +These operations operate on the .debug_pubnames section of the debugging +information. + +.H 3 "Debugger Interface Operations" + +.H 4 "dwarf_get_globals()" +.DS +\f(CWint dwarf_get_globals( + Dwarf_Debug dbg, + Dwarf_Global **globals, + Dwarf_Signed * return_count, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_get_globals()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_count\fP to +the count of pubnames +represented in the section containing pubnames i.e. .debug_pubnames. +It also stores at \f(CW*globals\fP, a pointer +to a list of \f(CWDwarf_Global\fP descriptors, one for each of the +pubnames in the .debug_pubnames section. +It returns \f(CWDW_DLV_ERROR\fP on error. +It returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_pubnames +section does not exist. + +.P +On a successful return from +\f(CWdwarf_get_globals()\fP, the \f(CWDwarf_Global\fP +descriptors should be +free'd using \f(CWdwarf_globals_dealloc()\fP. +\f(CWdwarf_globals_dealloc()\fP is new as of July 15, 2005 +and is the preferred approach to freeing this memory.. + +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Global *globs; +int res; + +res = dwarf_get_globals(dbg, &globs,&cnt, &error); +if (res == DW_DLV_OK) { + + for (i = 0; i < cnt; ++i) { + /* use globs[i] */ + } + dwarf_globals_dealloc(dbg, globs, cnt); +}\fP +.DE +.in -2 + + +.P +The following code is deprecated as of July 15, 2005 as it does not +free all relevant memory. +This approach still works as well as it ever did. +On a successful return from +\f(CWdwarf_get_globals()\fP, the \f(CWDwarf_Global\fP +descriptors should be individually +free'd using \f(CWdwarf_dealloc()\fP with the allocation type +\f(CWDW_DLA_GLOBAL_CONTEXT\fP, +(or +\f(CWDW_DLA_GLOBAL\fP, an older name, supported for compatibility) +followed by the deallocation of the list itself +with the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are +no longer of interest. + +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Global *globs; +int res; + +res = dwarf_get_globals(dbg, &globs,&cnt, &error); +if (res == DW_DLV_OK) { + + for (i = 0; i < cnt; ++i) { + /* use globs[i] */ + dwarf_dealloc(dbg, globs[i], DW_DLA_GLOBAL_CONTEXT); + } + dwarf_dealloc(dbg, globs, DW_DLA_LIST); +}\fP +.DE +.in -2 + +.H 4 "dwarf_globname()" +.DS +\f(CWint dwarf_globname( + Dwarf_Global global, + char ** return_name, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_globname()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to +a pointer to a +null-terminated string that names the pubname represented by the +\f(CWDwarf_Global\fP descriptor, \f(CWglobal\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +On a successful return from this function, the string should +be free'd using \f(CWdwarf_dealloc()\fP, with the allocation type +\f(CWDW_DLA_STRING\fP when no longer of interest. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 4 "dwarf_global_die_offset()" +.DS +\f(CWint dwarf_global_die_offset( + Dwarf_Global global, + Dwarf_Off *return_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_global_die_offset()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to +the offset in +the section containing DIE's, i.e. .debug_info, of the DIE representing +the pubname that is described by the \f(CWDwarf_Global\fP descriptor, +\f(CWglob\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 4 "dwarf_global_cu_offset()" +.DS +\f(CWint dwarf_global_cu_offset( + Dwarf_Global global, + Dwarf_Off *return_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_global_cu_offset()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to +the offset in +the section containing DIE's, i.e. .debug_info, of the compilation-unit +header of the compilation-unit that contains the pubname described +by the \f(CWDwarf_Global\fP descriptor, \f(CWglobal\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 4 "dwarf_get_cu_die_offset_given_cu_header_offset()" +.DS +\f(CWint dwarf_get_cu_die_offset_given_cu_header_offset( + Dwarf_Debug dbg, + Dwarf_Off in_cu_header_offset, + Dwarf_Off * out_cu_die_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_get_cu_die_offset_given_cu_header_offset()\fP +returns +\f(CWDW_DLV_OK\fP and sets \f(CW*out_cu_die_offset\fP to +the offset of the compilation-unit DIE given the +offset \f(CWin_cu_header_offset\fP of a compilation-unit header. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + + +This effectively turns a compilation-unit-header offset +into a compilation-unit DIE offset (by adding the +size of the applicable CU header). +This function is also sometimes useful with the +\f(CWdwarf_weak_cu_offset()\fP, +\f(CWdwarf_func_cu_offset()\fP, +\f(CWdwarf_type_cu_offset()\fP, +and +\f(CWint dwarf_var_cu_offset()\fP +functions. + +\f(CWdwarf_get_cu_die_offset_given_cu_header_offset()\fP +added Rev 1.45, June, 2001. + +This function is declared as 'optional' in libdwarf.h +on IRIX systems so the _MIPS_SYMBOL_PRESENT +predicate may be used at run time to determine if the version of +libdwarf linked into an application has this function. + +.H 4 "dwarf_global_name_offsets()" +.DS +\f(CWint dwarf_global_name_offsets( + Dwarf_Global global, + char **return_name, + Dwarf_Off *die_offset, + Dwarf_Off *cu_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_global_name_offsets()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to +a pointer to +a null-terminated string that gives the name of the pubname +described by the \f(CWDwarf_Global\fP descriptor \f(CWglobal\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. +It also returns in the locations +pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets +of the DIE representing the +pubname, and the DIE +representing the compilation-unit containing the +pubname, respectively. +On a +successful return from \f(CWdwarf_global_name_offsets()\fP the storage +pointed to by \f(CWreturn_name\fP +should be free'd using \f(CWdwarf_dealloc()\fP, +with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. + + +.H 2 "DWARF3 Type Names Operations" +Section ".debug_pubtypes" is new in DWARF3. +.P +These functions operate on the .debug_pubtypes section of the debugging +information. The .debug_pubtypes section contains the names of file-scope +user-defined types, the offsets of the \f(CWDIE\fPs that represent the +definitions of those types, and the offsets of the compilation-units +that contain the definitions of those types. + +.H 3 "Debugger Interface Operations" + +.H 4 "dwarf_get_pubtypes()" +.DS +\f(CWint dwarf_get_pubtypes( + Dwarf_Debug dbg, + Dwarf_Type **types, + Dwarf_Signed *typecount, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_get_pubtypes()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*typecount\fP to +the count of user-defined +type names represented in the section containing user-defined type names, +i.e. .debug_pubtypes. +It also stores at \f(CW*types\fP, +a pointer to a list of \f(CWDwarf_Pubtype\fP descriptors, one for each of the +user-defined type names in the .debug_pubtypes section. +It returns \f(CWDW_DLV_NOCOUNT\fP on error. +It returns \f(CWDW_DLV_NO_ENTRY\fP if +the .debug_pubtypes section does not exist. + +.P +On a successful +return from \f(CWdwarf_get_pubtypes()\fP, +the \f(CWDwarf_Type\fP descriptors should be +free'd using \f(CWdwarf_types_dealloc()\fP. +\f(CWdwarf_types_dealloc()\fP is used for both +\f(CWdwarf_get_pubtypes()\fP and \f(CWdwarf_get_types()\fP +as the data types are the same. + +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Pubtype *types; +int res; + +res = dwarf_get_pubtypes(dbg, &types,&cnt, &error); +if (res == DW_DLV_OK) { + + for (i = 0; i < cnt; ++i) { + /* use types[i] */ + } + dwarf_types_dealloc(dbg, types, cnt); +}\fP +.DE +.in -2 + +.H 4 "dwarf_pubtypename()" +.DS +\f(CWint dwarf_pubtypename( + Dwarf_Pubtype type, + char **return_name, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_pubtypename()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to +a pointer to a +null-terminated string that names the user-defined type represented by the +\f(CWDwarf_Pubtype\fP descriptor, \f(CWtype\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. +On a successful return from this function, the string should +be free'd using \f(CWdwarf_dealloc()\fP, with the allocation type +\f(CWDW_DLA_STRING\fP when no longer of interest. + +.H 4 "dwarf_pubtype_die_offset()" +.DS +\f(CWint dwarf_pubtype_die_offset( + Dwarf_Pubtype type, + Dwarf_Off *return_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_pubtype_die_offset()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to +the offset in +the section containing DIE's, i.e. .debug_info, of the DIE representing +the user-defined type that is described by the \f(CWDwarf_Pubtype\fP +descriptor, \f(CWtype\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 4 "dwarf_pubtype_cu_offset()" +.DS +\f(CWint dwarf_pubtype_cu_offset( + Dwarf_Pubtype type, + Dwarf_Off *return_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_pubtype_cu_offset()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to +the offset in +the section containing DIE's, i.e. .debug_info, of the compilation-unit +header of the compilation-unit that contains the user-defined type +described by the \f(CWDwarf_Pubtype\fP descriptor, \f(CWtype\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 4 "dwarf_pubtype_name_offsets()" +.DS +\f(CWint dwarf_pubtype_name_offsets( + Dwarf_Pubtype type, + char ** returned_name, + Dwarf_Off * die_offset, + Dwarf_Off * cu_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_pubtype_name_offsets()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to +a pointer to +a null-terminated string that gives the name of the user-defined +type described by the \f(CWDwarf_Pubtype\fP descriptor \f(CWtype\fP. +It also returns in the locations +pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets +of the DIE representing the +user-defined type, and the DIE +representing the compilation-unit containing the +user-defined type, respectively. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. +On a successful return from \f(CWdwarf_pubtype_name_offsets()\fP +the storage pointed to by \f(CWreturned_name\fP should +be free'd using +\f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP +when no longer of interest. + + +.H 2 "User Defined Static Variable Names Operations" +This section is SGI specific and is not part of standard DWARF version 2. +.P +These functions operate on the .debug_varnames section of the debugging +information. The .debug_varnames section contains the names of file-scope +static variables, the offsets of the \f(CWDIE\fPs that represent the +definitions of those variables, and the offsets of the compilation-units +that contain the definitions of those variables. +.P + + +.H 2 "Weak Name Space Operations" +These operations operate on the .debug_weaknames section of the debugging +information. +.P +These operations are SGI specific, not part of standard DWARF. +.P + +.H 3 "Debugger Interface Operations" + +.H 4 "dwarf_get_weaks()" +.DS +\f(CWint dwarf_get_weaks( + Dwarf_Debug dbg, + Dwarf_Weak **weaks, + Dwarf_Signed *weak_count, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_get_weaks()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*weak_count\fP to +the count of weak names +represented in the section containing weak names i.e. .debug_weaknames. +It returns \f(CWDW_DLV_ERROR\fP on error. +It returns \f(CWDW_DLV_NO_ENTRY\fP if the section does not exist. +It also stores in \f(CW*weaks\fP, a pointer to +a list of \f(CWDwarf_Weak\fP descriptors, one for each of the weak names +in the .debug_weaknames section. + +.P +On a successful return from this function, +the \f(CWDwarf_Weak\fP descriptors should be free'd using +\f(CWdwarf_weaks_dealloc()\fP when the data is no longer of +interest. \f(CWdwarf_weaks_dealloc()\fPis new as of July 15, 2005. + +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Weak *weaks; +int res; + +res = dwarf_get_weaks(dbg, &weaks,&cnt, &error); +if (res == DW_DLV_OK) { + + for (i = 0; i < cnt; ++i) { + /* use weaks[i] */ + } + dwarf_weaks_dealloc(dbg, weaks, cnt); +}\fP +.DE +.in -2 + + + +.P +The following code is deprecated as of July 15, 2005 as it does not +free all relevant memory. +This approach still works as well as it ever did. +On a successful return from \f(CWdwarf_get_weaks()\fP +the \f(CWDwarf_Weak\fP descriptors should be individually free'd using +\f(CWdwarf_dealloc()\fP with the allocation type +\f(CWDW_DLA_WEAK_CONTEXT\fP, +(or +\f(CWDW_DLA_WEAK\fP, an older name, supported for compatibility) +followed by the deallocation of the list itself with the allocation type +\f(CWDW_DLA_LIST\fP when the descriptors are no longer of interest. + +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Weak *weaks; +int res; + +res = dwarf_get_weaks(dbg, &weaks,&cnt, &error); +if (res == DW_DLV_OK) { + + for (i = 0; i < cnt; ++i) { + /* use weaks[i] */ + dwarf_dealloc(dbg, weaks[i], DW_DLA_WEAK_CONTEXT); + } + dwarf_dealloc(dbg, weaks, DW_DLA_LIST); +}\fP +.DE +.in -2 + +.H 4 "dwarf_weakname()" +.DS +\f(CWint dwarf_weakname( + Dwarf_Weak weak, + char ** return_name, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_weakname()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to +a pointer to a null-terminated +string that names the weak name represented by the +\f(CWDwarf_Weak\fP descriptor, \f(CWweak\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. +On a successful return from this function, the string should +be free'd using \f(CWdwarf_dealloc()\fP, with the allocation type +\f(CWDW_DLA_STRING\fP when no longer of interest. + +.DS +\f(CWint dwarf_weak_die_offset( + Dwarf_Weak weak, + Dwarf_Off *return_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_weak_die_offset()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in +the section containing DIE's, i.e. .debug_info, of the DIE representing +the weak name that is described by the \f(CWDwarf_Weak\fP descriptor, +\f(CWweak\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 4 "dwarf_weak_cu_offset()" +.DS +\f(CWint dwarf_weak_cu_offset( + Dwarf_Weak weak, + Dwarf_Off *return_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_weak_cu_offset()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in +the section containing DIE's, i.e. .debug_info, of the compilation-unit +header of the compilation-unit that contains the weak name described +by the \f(CWDwarf_Weak\fP descriptor, \f(CWweak\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 4 "dwarf_weak_name_offsets()" +.DS +\f(CWint dwarf_weak_name_offsets( + Dwarf_Weak weak, + char ** weak_name, + Dwarf_Off *die_offset, + Dwarf_Off *cu_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_weak_name_offsets()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*weak_name\fP to +a pointer to +a null-terminated string that gives the name of the weak name +described by the \f(CWDwarf_Weak\fP descriptor \f(CWweak\fP. +It also returns in the locations +pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets +of the DIE representing the +weakname, and the DIE +representing the compilation-unit containing the +weakname, respectively. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. +On a +successful return from \f(CWdwarf_weak_name_offsets()\fP the storage +pointed to by \f(CWweak_name\fP +should be free'd using \f(CWdwarf_dealloc()\fP, +with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. + +.H 2 "Static Function Names Operations" +This section is SGI specific and is not part of standard DWARF version 2. +.P +These function operate on the .debug_funcnames section of the debugging +information. The .debug_funcnames section contains the names of static +functions defined in the object, the offsets of the \f(CWDIE\fPs that +represent the definitions of the corresponding functions, and the offsets +of the start of the compilation-units that contain the definitions of +those functions. + +.H 3 "Debugger Interface Operations" + +.H 4 "dwarf_get_funcs()" +.DS +\f(CWint dwarf_get_funcs( + Dwarf_Debug dbg, + Dwarf_Func **funcs, + Dwarf_Signed *func_count, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_get_funcs()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*func_count\fP to +the count of static +function names represented in the section containing static function +names, i.e. .debug_funcnames. +It also +stores, at \f(CW*funcs\fP, a pointer to a list of \f(CWDwarf_Func\fP +descriptors, one for each of the static functions in the .debug_funcnames +section. +It returns \f(CWDW_DLV_NOCOUNT\fP on error. +It returns \f(CWDW_DLV_NO_ENTRY\fP +if the .debug_funcnames section does not exist. +.P +On a successful return from \f(CWdwarf_get_funcs()\fP, +the \f(CWDwarf_Func\fP +descriptors should be free'd using \f(CWdwarf_funcs_dealloc()\fP. +\f(CWdwarf_funcs_dealloc()\fP is new as of July 15, 2005. + +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Func *funcs; +int fres; + +fres = dwarf_get_funcs(dbg, &funcs, &error); +if (fres == DW_DLV_OK) { + + for (i = 0; i < cnt; ++i) { + /* use funcs[i] */ + } + dwarf_funcs_dealloc(dbg, funcs, cnt); +}\fP +.DE +.in -2 + + +.P +The following code is deprecated as of July 15, 2005 as it does not +free all relevant memory. +This approach still works as well as it ever did. +On a successful return from \f(CWdwarf_get_funcs()\fP, +the \f(CWDwarf_Func\fP +descriptors should be individually free'd using \f(CWdwarf_dealloc()\fP +with the allocation type +\f(CWDW_DLA_FUNC_CONTEXT\fP, +(or +\f(CWDW_DLA_FUNC\fP, an older name, supported for compatibility) +followed by the deallocation +of the list itself with the allocation type \f(CWDW_DLA_LIST\fP when +the descriptors are no longer of interest. + +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Func *funcs; +int fres; + +fres = dwarf_get_funcs(dbg, &funcs, &error); +if (fres == DW_DLV_OK) { + + for (i = 0; i < cnt; ++i) { + /* use funcs[i] */ + dwarf_dealloc(dbg, funcs[i], DW_DLA_FUNC_CONTEXT); + } + dwarf_dealloc(dbg, funcs, DW_DLA_LIST); +}\fP +.DE +.in -2 + +.H 4 "dwarf_funcname()" +.DS +\f(CWint dwarf_funcname( + Dwarf_Func func, + char ** return_name, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_funcname()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to +a pointer to a +null-terminated string that names the static function represented by the +\f(CWDwarf_Func\fP descriptor, \f(CWfunc\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. +On a successful return from this function, the string should +be free'd using \f(CWdwarf_dealloc()\fP, with the allocation type +\f(CWDW_DLA_STRING\fP when no longer of interest. + +.H 4 "dwarf_func_die_offset()" +.DS +\f(CWint dwarf_func_die_offset( + Dwarf_Func func, + Dwarf_Off *return_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_func_die_offset()\fP, returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to +the offset in +the section containing DIE's, i.e. .debug_info, of the DIE representing +the static function that is described by the \f(CWDwarf_Func\fP +descriptor, \f(CWfunc\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 4 "dwarf_func_cu_offset()" +.DS +\f(CWint dwarf_func_cu_offset( + Dwarf_Func func, + Dwarf_Off *return_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_func_cu_offset()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to +the offset in +the section containing DIE's, i.e. .debug_info, of the compilation-unit +header of the +compilation-unit that contains the static function +described by the \f(CWDwarf_Func\fP descriptor, \f(CWfunc\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 4 "dwarf_func_name_offsets()" +.DS +\f(CWint dwarf_func_name_offsets( + Dwarf_Func func, + char **func_name, + Dwarf_Off *die_offset, + Dwarf_Off *cu_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_func_name_offsets()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*func_name\fP to +a pointer to +a null-terminated string that gives the name of the static +function described by the \f(CWDwarf_Func\fP descriptor \f(CWfunc\fP. +It also returns in the locations +pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets +of the DIE representing the +static function, and the DIE +representing the compilation-unit containing the +static function, respectively. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. +On a successful return from \f(CWdwarf_func_name_offsets()\fP +the storage pointed to by \f(CWfunc_name\fP should be free'd using +\f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP +when no longer of interest. + +.H 2 "User Defined Type Names Operations" +Section "debug_typenames" is SGI specific +and is not part of standard DWARF version 2. +(However, an identical section is part of DWARF version 3 +named ".debug_pubtypes", see \f(CWdwarf_get_pubtypes()\fP above.) +.P +These functions operate on the .debug_typenames section of the debugging +information. The .debug_typenames section contains the names of file-scope +user-defined types, the offsets of the \f(CWDIE\fPs that represent the +definitions of those types, and the offsets of the compilation-units +that contain the definitions of those types. + +.H 3 "Debugger Interface Operations" + +.H 4 "dwarf_get_types()" +.DS +\f(CWint dwarf_get_types( + Dwarf_Debug dbg, + Dwarf_Type **types, + Dwarf_Signed *typecount, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_get_types()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*typecount\fP to +the count of user-defined +type names represented in the section containing user-defined type names, +i.e. .debug_typenames. +It also stores at \f(CW*types\fP, +a pointer to a list of \f(CWDwarf_Type\fP descriptors, one for each of the +user-defined type names in the .debug_typenames section. +It returns \f(CWDW_DLV_NOCOUNT\fP on error. +It returns \f(CWDW_DLV_NO_ENTRY\fP if +the .debug_typenames section does not exist. + +.P + +On a successful +return from \f(CWdwarf_get_types()\fP, +the \f(CWDwarf_Type\fP descriptors should be +free'd using \f(CWdwarf_types_dealloc()\fP. +\f(CWdwarf_types_dealloc()\fP is new as of July 15, 2005 +and frees all memory allocated by \f(CWdwarf_get_types()\fP. + +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Type *types; +int res; + +res = dwarf_get_types(dbg, &types,&cnt, &error); +if (res == DW_DLV_OK) { + + for (i = 0; i < cnt; ++i) { + /* use types[i] */ + } + dwarf_types_dealloc(dbg, types, cnt); +}\fP +.DE +.in -2 + + + +.P +The following code is deprecated as of July 15, 2005 as it does not +free all relevant memory. +This approach still works as well as it ever did. +On a successful +return from \f(CWdwarf_get_types()\fP, +the \f(CWDwarf_Type\fP descriptors should be +individually free'd using \f(CWdwarf_dealloc()\fP with the allocation type +\f(CWDW_DLA_TYPENAME_CONTEXT\fP, +(or +\f(CWDW_DLA_TYPENAME\fP, an older name, supported for compatibility) +followed by the deallocation of the list itself +with the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are no +longer of interest. + +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Type *types; +int res; + +res = dwarf_get_types(dbg, &types,&cnt, &error); +if (res == DW_DLV_OK) { + + for (i = 0; i < cnt; ++i) { + /* use types[i] */ + dwarf_dealloc(dbg, types[i], DW_DLA_TYPENAME_CONTEXT); + } + dwarf_dealloc(dbg, types, DW_DLA_LIST); +}\fP +.DE +.in -2 + +.H 4 "dwarf_typename()" +.DS +\f(CWint dwarf_typename( + Dwarf_Type type, + char **return_name, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_typename()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to +a pointer to a +null-terminated string that names the user-defined type represented by the +\f(CWDwarf_Type\fP descriptor, \f(CWtype\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. +On a successful return from this function, the string should +be free'd using \f(CWdwarf_dealloc()\fP, with the allocation type +\f(CWDW_DLA_STRING\fP when no longer of interest. + +.H 4 "dwarf_type_die_offset()" +.DS +\f(CWint dwarf_type_die_offset( + Dwarf_Type type, + Dwarf_Off *return_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_type_die_offset()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to +the offset in +the section containing DIE's, i.e. .debug_info, of the DIE representing +the user-defined type that is described by the \f(CWDwarf_Type\fP +descriptor, \f(CWtype\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 4 "dwarf_type_cu_offset()" +.DS +\f(CWint dwarf_type_cu_offset( + Dwarf_Type type, + Dwarf_Off *return_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_type_cu_offset()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to +the offset in +the section containing DIE's, i.e. .debug_info, of the compilation-unit +header of the compilation-unit that contains the user-defined type +described by the \f(CWDwarf_Type\fP descriptor, \f(CWtype\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 4 "dwarf_type_name_offsets()" +.DS +\f(CWint dwarf_type_name_offsets( + Dwarf_Type type, + char ** returned_name, + Dwarf_Off * die_offset, + Dwarf_Off * cu_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_type_name_offsets()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to +a pointer to +a null-terminated string that gives the name of the user-defined +type described by the \f(CWDwarf_Type\fP descriptor \f(CWtype\fP. +It also returns in the locations +pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets +of the DIE representing the +user-defined type, and the DIE +representing the compilation-unit containing the +user-defined type, respectively. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. +On a successful return from \f(CWdwarf_type_name_offsets()\fP +the storage pointed to by \f(CWreturned_name\fP should +be free'd using +\f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP +when no longer of interest. + + +.H 2 "User Defined Static Variable Names Operations" +This section is SGI specific and is not part of standard DWARF version 2. +.P +These functions operate on the .debug_varnames section of the debugging +information. The .debug_varnames section contains the names of file-scope +static variables, the offsets of the \f(CWDIE\fPs that represent the +definitions of those variables, and the offsets of the compilation-units +that contain the definitions of those variables. +.P + +.H 3 "Debugger Interface Operations" + +.H 4 "dwarf_get_vars()" + +.DS +\f(CWint dwarf_get_vars( + Dwarf_Debug dbg, + Dwarf_Var **vars, + Dwarf_Signed *var_count, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_get_vars()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*var_count\fP to +the count of file-scope +static variable names represented in the section containing file-scope +static variable names, i.e. .debug_varnames. +It also stores, at \f(CW*vars\fP, a pointer to a list of +\f(CWDwarf_Var\fP descriptors, one for each of the file-scope static +variable names in the .debug_varnames section. +It returns \f(CWDW_DLV_ERROR\fP on error. +It returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_varnames section does +not exist. + +.P +The following is new as of July 15, 2005. +On a successful return +from \f(CWdwarf_get_vars()\fP, the \f(CWDwarf_Var\fP descriptors should be +free'd using \f(CWdwarf_vars_dealloc()\fP. + +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Var *vars; +int res; + +res = dwarf_get_vars(dbg, &vars,&cnt &error); +if (res == DW_DLV_OK) { + + for (i = 0; i < cnt; ++i) { + /* use vars[i] */ + } + dwarf_vars_dealloc(dbg, vars, cnt); +}\fP +.DE +.in -2 + +.P +The following code is deprecated as of July 15, 2005 as it does not +free all relevant memory. +This approach still works as well as it ever did. +On a successful return +from \f(CWdwarf_get_vars()\fP, the \f(CWDwarf_Var\fP descriptors should be individually +free'd using \f(CWdwarf_dealloc()\fP with the allocation type +\f(CWDW_DLA_VAR_CONTEXT\fP, +(or +\f(CWDW_DLA_VAR\fP, an older name, supported for compatibility) +followed by the deallocation of the list itself with +the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are no +longer of interest. + +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Var *vars; +int res; + +res = dwarf_get_vars(dbg, &vars,&cnt &error); +if (res == DW_DLV_OK) { + + for (i = 0; i < cnt; ++i) { + /* use vars[i] */ + dwarf_dealloc(dbg, vars[i], DW_DLA_VAR_CONTEXT); + } + dwarf_dealloc(dbg, vars, DW_DLA_LIST); +}\fP +.DE +.in -2 + +.H 4 "dwarf_varname()" +.DS +\f(CWint dwarf_varname( + Dwarf_Var var, + char ** returned_name, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_varname()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to +a pointer to a +null-terminated string that names the file-scope static variable represented +by the \f(CWDwarf_Var\fP descriptor, \f(CWvar\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. +On a successful return from this function, the string should +be free'd using \f(CWdwarf_dealloc()\fP, with the allocation type +\f(CWDW_DLA_STRING\fP when no longer of interest. + +.H 4 "dwarf_var_die_offset()" +.DS +\f(CWint dwarf_var_die_offset( + Dwarf_Var var, + Dwarf_Off *returned_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_var_die_offset()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*returned_offset\fP to +the offset in +the section containing DIE's, i.e. .debug_info, of the DIE representing +the file-scope static variable that is described by the \f(CWDwarf_Var\fP +descriptor, \f(CWvar\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 4 "dwarf_var_cu_offset()" +.DS +\f(CWint dwarf_var_cu_offset( + Dwarf_Var var, + Dwarf_Off *returned_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_var_cu_offset()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*returned_offset\fP to +the offset in +the section containing DIE's, i.e. .debug_info, of the compilation-unit +header of the compilation-unit that contains the file-scope static +variable described by the \f(CWDwarf_Var\fP descriptor, \f(CWvar\fP. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 4 "dwarf_var_name_offsets()" +.DS +\f(CWint dwarf_var_name_offsets( + Dwarf_Var var, + char **returned_name, + Dwarf_Off *die_offset, + Dwarf_Off *cu_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_var_name_offsets()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to +a pointer to +a null-terminated string that gives the name of the file-scope +static variable described by the \f(CWDwarf_Var\fP descriptor \f(CWvar\fP. +It also returns in the locations +pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets +of the DIE representing the +file-scope static variable, and the DIE +representing the compilation-unit containing the +file-scope static variable, respectively. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. +On a successful return from +\f(CWdwarf_var_name_offsets()\fP the storage pointed to by +\f(CWreturned_name\fP +should be free'd using \f(CWdwarf_dealloc()\fP, with the allocation +type \f(CWDW_DLA_STRING\fP when no longer of interest. + +.H 2 "Macro Information Operations" +.H 3 "General Macro Operations" +.H 4 "dwarf_find_macro_value_start()" +.DS +\f(CWchar *dwarf_find_macro_value_start(char * macro_string);\fP +.DE +Given a macro string in the standard form defined in the DWARF +document ("name value" or "name(args)value") +this returns a pointer to the first byte of the macro value. +It does not alter the string pointed to by macro_string or copy +the string: it returns a pointer into the string whose +address was passed in. +.H 3 "Debugger Interface Macro Operations" +Macro information is accessed from the .debug_info section via the +DW_AT_macro_info attribute (whose value is an offset into .debug_macinfo). +.P +No Functions yet defined. +.H 3 "Low Level Macro Information Operations" +.H 4 "dwarf_get_macro_details()" +.DS +\f(CWint dwarf_get_macro_details(Dwarf_Debug /*dbg*/, + Dwarf_Off macro_offset, + Dwarf_Unsigned maximum_count, + Dwarf_Signed * entry_count, + Dwarf_Macro_Details ** details, + Dwarf_Error * err);\fP +.DE +\f(CWdwarf_get_macro_details()\fP +returns +\f(CWDW_DLV_OK\fP and sets +\f(CWentry_count\fP to the number of \f(CWdetails\fP records +returned through the \f(CWdetails\fP pointer. +The data returned thru \f(CWdetails\fP should be freed +by a call to \f(CWdwarf_dealloc()\fP with the allocation type +\f(CWDW_DLA_STRING\fP. +If \f(CWDW_DLV_OK\fP is returned, the \f(CWentry_count\fP will +be at least 1, since +a compilation unit with macro information but no macros will +have at least one macro data byte of 0. +.P +\f(CWdwarf_get_macro_details()\fP +begins at the \f(CWmacro_offset\fP offset you supply +and ends at the end of a compilation unit or at \f(CWmaximum_count\fP +detail records (whichever comes first). +If \f(CWmaximum_count\fP is 0, it is treated as if it were the maximum +possible unsigned integer. +.P +\f(CWdwarf_get_macro_details()\fP +attempts to set \f(CWdmd_fileindex\fP to the correct file in every +\f(CWdetails\fP record. If it is unable to do so (or whenever +the current file index is unknown, it sets \f(CWdmd_fileindex\fP +to -1. +.P +\f(CWdwarf_get_macro_details()\fP returns \f(CWDW_DLV_ERROR\fP on error. +It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no more +macro information at that \f(CWmacro_offset\fP. If \f(CWmacro_offset\fP +is passed in as 0, a \f(CWDW_DLV_NO_ENTRY\fP return means there is +no macro information. +.P +.in +2 +.DS +\f(CWDwarf_Unsigned max = 0; +Dwarf_Off cur_off = 0; +Dwarf_Signed count = 0; +Dwarf_Macro_Details *maclist; +int errv; + +/* loop thru all the compilation units macro info */ +while((errv = dwarf_macro_details(dbg, cur_off,max, + &count,&maclist,&error))== DW_DLV_OK) { + for (i = 0; i < count; ++i) { + /* use maclist[i] */ + } + cur_off = maclist[count-1].dmd_offset + 1; + dwarf_dealloc(dbg, maclist, DW_DLA_STRING); +}\fP +.DE + + +.H 2 "Low Level Frame Operations" +These functions provide information about stack frames to be +used to perform stack traces. The information is an abstraction +of a table with a row per instruction and a column per register +and a column for the canonical frame address (CFA, which corresponds +to the notion of a frame pointer), +as well as a column for the return address. +.P +From 1993-2006 the interface we'll here refer to as DWARF2 +made the CFA be a column in the matrix, but left +DW_FRAME_UNDEFINED_VAL, and DW_FRAME_SAME_VAL out of the matrix +(giving them high numbers). As of the DWARF3 interfaces +introduced in this document in April 2006, there are *two* +interfaces. +.P +The original still exists (see. +dwarf_get_fde_info_for_reg() and dwarf_get_fde_info_for_all_regs() below) +and works adequately for MIPS/IRIX DWARF2 and ABI/ISA sets +that are sufficiently similar (but the settings for non-MIPS +must be set into libdwarf.h and cannot be changed at runtime). +.P +A new interface set of dwarf_get_fde_info_for_reg3(), +dwarf_get_fde_info_for_cfa_reg3(), dwarf_get_fde_info_for_all_regs3() +dwarf_set_frame_rule_inital_value(), dwarf_set_frame_rule_table_size() +is more flexible +and should work for many more architectures +and the setting of DW_FRAME_CFA_COL and the size of +the table can be set at runtime. +.P +Each cell in the table contains one of the following: + +.AL +.LI +A register + offset(a)(b) + +.LI +A register(c)(d) + + +.LI +A marker (DW_FRAME_UNDEFINED_VAL) meaning \fIregister value undefined\fP + +.LI +A marker (DW_FRAME_SAME_VAL) meaning \fIregister value same as in caller\fP +.LE +.P +(a old DWARF2 interface) When the column is DW_FRAME_CFA_COL: the register +number is a real hardware register, not a reference +to DW_FRAME_CFA_COL, not DW_FRAME_UNDEFINED_VAL, +and not DW_FRAME_SAME_VAL. +The CFA rule value should be the stack pointer +plus offset 0 when no other value makes sense. +A value of DW_FRAME_SAME_VAL would +be semi-logical, but since the CFA is not a real register, +not really correct. +A value of DW_FRAME_UNDEFINED_VAL would imply +the CFA is undefined -- +this seems to be a useless notion, as +the CFA is a means to finding real registers, +so those real registers should be marked DW_FRAME_UNDEFINED_VAL, +and the CFA column content (whatever register it +specifies) becomes unreferenced by anything. +.P +(a new April 2006 DWARF2/3 interface): The CFA is +separately accessible and not part of the table. +The 'rule number' for the CFA is a number outside the table. +So the CFA is a marker, not a register number. +See DW_FRAME_CFA_COL3 in libdwarf.h and +dwarf_get_fde_info_for_cfa_reg3(). +.P +(b) When the column is not DW_FRAME_CFA_COL, the 'register' +will and must be DW_FRAME_CFA_COL, implying that +to get the final location for the column one must add +the offset here plus the DW_FRAME_CFA_COL rule value. +.P +(c) When the column is DW_FRAME_CFA_COL, then the register +number is (must be) a real hardware register . +If it were DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL +it would be a marker, not a register number. +.P +(d) When the column is not DW_FRAME_CFA_COL, the register +may be a hardware register. +It will not be DW_FRAME_CFA_COL. +.P +There is no 'column' for DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL. + +Figure \n(aX +is machine dependent and represents MIPS cpu register +assignments. + +.DS +.TS +center box, tab(:); +lfB lfB lfB +l c l. +NAME:value:PURPOSE +_ +DW_FRAME_CFA_COL:0:column used for CFA +DW_FRAME_REG1:1:integer regster 1 +DW_FRAME_REG2:2:integer register 2 +---::obvious names and values here +DW_FRAME_REG30:30:integer register 30 +DW_FRAME_REG31:31:integer register 31 +DW_FRAME_FREG0:32:floating point register 0 +DW_FRAME_FREG1:33:floating point register 1 +---::obvious names and values here +DW_FRAME_FREG30:62:floating point register 30 +DW_FRAME_FREG31:63:floating point register 31 +DW_FRAME_RA_COL:64:column recording ra +DW_FRAME_UNDEFINED_VAL:1034:register val undefined +DW_FRAME_SAME_VAL:1035:register same as in caller +.TE + +.FG "Frame Information Rule Assignments" +.DE + +.P +The following table shows SGI/MIPS specific +special cell values: these values mean +that the cell has the value \fIundefined\fP or \fIsame value\fP +respectively, rather than containing a \fIregister\fP or +\fIregister+offset\fP. +It assumes DW_FRAME_CFA_COL is a table rule, which +is not readily accomplished or sensible for some architectures. +.P +.DS +.TS +center box, tab(:); +lfB lfB lfB +l c l. +NAME:value:PURPOSE +_ +DW_FRAME_UNDEFINED_VAL:1034:means undefined value. +::Not a column or register value +DW_FRAME_SAME_VAL:1035:means 'same value' as +::caller had. Not a column or +::register value +.TE +.FG "Frame Information Special Values" +.DE + +.P +The following table shows more general special cell values. +These values mean +that the cell register-number refers to the \fIcfa-register\fP or +\fIundefined-value\fP or \fIsame-value\fP +respectively, rather than referring to a \fIregister in the table\fP. +The generality arises from making DW_FRAME_CFA_COL3 be +outside the set of registers and making the cfa rule accessible +from outside the rule-table. +.P +.DS +.TS +center box, tab(:); +lfB lfB lfB +l c l. +NAME:value:PURPOSE +_ +DW_FRAME_UNDEFINED_VAL:1034:means undefined value. +::Not a column or register value +DW_FRAME_SAME_VAL:1035:means 'same value' as +::caller had. Not a column or +::register value +DW_FRAME_CFA_COL3:1036:means 'cfa register'is referred to, +::not a real register, not a column, but the cfa (the cfa +::does have a value, but in the DWARF3 libdwarf interface +::it does not have a 'real register number'). +.TE +.DE +.\"#if 0 +.\".P +.\"Since the cie and fde entries are not "organized" by anything +.\"outside of the .debug_frame section one must scan them all to +.\"find all entry addresses and lengths. Since there is one fde +.\"per function this can be a rather long list. +.\"#endif + +.P +.H 4 "dwarf_get_fde_list()" +.DS +\f(CWint dwarf_get_fde_list( + Dwarf_Debug dbg, + Dwarf_Cie **cie_data, + Dwarf_Signed *cie_element_count, + Dwarf_Fde **fde_data, + Dwarf_Signed *fde_element_count, + Dwarf_Error *error);\fP +.DE +\f(CWdwarf_get_fde_list()\fP stores a pointer to a list of +\f(CWDwarf_Cie\fP descriptors in \f(CW*cie_data\fP, and the +count of the number of descriptors in \f(CW*cie_element_count\fP. +There is a descriptor for each CIE in the .debug_frame section. +Similarly, it stores a pointer to a list of \f(CWDwarf_Fde\fP +descriptors in \f(CW*fde_data\fP, and the count of the number +of descriptors in \f(CW*fde_element_count\fP. There is one +descriptor per FDE in the .debug_frame section. +\f(CWdwarf_get_fde_list()\fP returns \f(CWDW_DLV_EROR\fP on error. +It returns \f(CWDW_DLV_NO_ENTRY\fP if it cannot find frame entries. +It returns \f(CWDW_DLV_OK\fP on a successful return. +.P +On successful return, structures pointed to by a +descriptor should be free'd using \f(CWdwarf_fde_cie_list_dealloc()\fP. +This dealloc approach is new as of July 15, 2005. + +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Cie *cie_data; +Dwarf_Signed cie_count; +Dwarf_Fde *fde_data; +Dwarf_Signed fde_count; +int fres; + +fres = dwarf_get_fde_list(dbg,&cie_data,&cie_count, + &fde_data,&fde_count,&error); +if (fres == DW_DLV_OK) { + dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_count, + fde_data,fde_count); +}\fP +.DE +.in -2 + + + +.P +The following code is deprecated as of July 15, 2005 as it does not +free all relevant memory. +This approach still works as well as it ever did. +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Cie *cie_data; +Dwarf_Signed cie_count; +Dwarf_Fde *fde_data; +Dwarf_Signed fde_count; +int fres; + +fres = dwarf_get_fde_list(dbg,&cie_data,&cie_count, + &fde_data,&fde_count,&error); +if (fres == DW_DLV_OK) { + + for (i = 0; i < cie_count; ++i) { + /* use cie[i] */ + dwarf_dealloc(dbg, cie_data[i], DW_DLA_CIE); + } + for (i = 0; i < fde_count; ++i) { + /* use fde[i] */ + dwarf_dealloc(dbg, fde_data[i], DW_DLA_FDE); + } + dwarf_dealloc(dbg, cie_data, DW_DLA_LIST); + dwarf_dealloc(dbg, fde_data, DW_DLA_LIST); +}\fP +.DE +.in -2 + +.P +.H 4 "dwarf_get_fde_list_eh()" +.DS +\f(CWint dwarf_get_fde_list_eh( + Dwarf_Debug dbg, + Dwarf_Cie **cie_data, + Dwarf_Signed *cie_element_count, + Dwarf_Fde **fde_data, + Dwarf_Signed *fde_element_count, + Dwarf_Error *error);\fP +.DE +\f(CWdwarf_get_fde_list_eh()\fP is identical to +\f(CWdwarf_get_fde_list()\fP except that +\f(CWdwarf_get_fde_list_eh()\fP reads the GNU ecgs +section named .eh_frame (C++ exception handling information). + +\f(CWdwarf_get_fde_list_eh()\fP stores a pointer to a list of +\f(CWDwarf_Cie\fP descriptors in \f(CW*cie_data\fP, and the +count of the number of descriptors in \f(CW*cie_element_count\fP. +There is a descriptor for each CIE in the .debug_frame section. +Similarly, it stores a pointer to a list of \f(CWDwarf_Fde\fP +descriptors in \f(CW*fde_data\fP, and the count of the number +of descriptors in \f(CW*fde_element_count\fP. There is one +descriptor per FDE in the .debug_frame section. +\f(CWdwarf_get_fde_list()\fP returns \f(CWDW_DLV_EROR\fP on error. +It returns \f(CWDW_DLV_NO_ENTRY\fP if it cannot find +exception handling entries. +It returns \f(CWDW_DLV_OK\fP on a successful return. + +.P +On successful return, structures pointed to by a +descriptor should be free'd using \f(CWdwarf_fde_cie_list_dealloc()\fP. +This dealloc approach is new as of July 15, 2005. + +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Cie *cie_data; +Dwarf_Signed cie_count; +Dwarf_Fde *fde_data; +Dwarf_Signed fde_count; +int fres; + +fres = dwarf_get_fde_list(dbg,&cie_data,&cie_count, + &fde_data,&fde_count,&error); +if (fres == DW_DLV_OK) { + dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_count, + fde_data,fde_count); +}\fP +.DE +.in -2 + + +.P +.H 4 "dwarf_get_cie_of_fde()" +.DS +\f(CWint dwarf_get_cie_of_fde(Dwarf_Fde fde, + Dwarf_Cie *cie_returned, + Dwarf_Error *error);\fP +.DE +\f(CWdwarf_get_cie_of_fde()\fP stores a \f(CWDwarf_Cie\fP +into the \f(CWDwarf_Cie\fP that \f(CWcie_returned\fP points at. + +If one has called dwarf_get_fde_list and does not wish +to dwarf_dealloc() all the individual FDEs immediately, one +must also avoid dwarf_dealloc-ing the CIEs for those FDEs +not immediately dealloc'd. +Failing to observe this restriction will cause the FDE(s) not +dealloced to become invalid: an FDE contains (hidden in it) +a CIE pointer which will be be invalid (stale, pointing to freed memory) +if the CIE is dealloc'd. +The invalid CIE pointer internal to the FDE cannot be detected +as invalid by libdwarf. +If one later passes an FDE with a stale internal CIE pointer +to one of the routines taking an FDE as input the result will +be failure of the call (returning DW_DLV_ERROR) at best and +it is possible a coredump or worse will happpen (eventually). + + +\f(CWdwarf_get_cie_of_fde()\fP returns +\f(CWDW_DLV_OK\fP if it is successful (it will be +unless fde is the NULL pointer). +It returns \f(CWDW_DLV_ERROR\fP if the fde is invalid (NULL). + +.P +Each \f(CWDwarf_Fde\fP descriptor describes information about the +frame for a particular subroutine or function. + +\f(CWint dwarf_get_fde_for_die\fP is SGI/MIPS specific. + +.H 4 "dwarf_get_fde_for_die()" +.DS +\f(CWint dwarf_get_fde_for_die( + Dwarf_Debug dbg, + Dwarf_Die die, + Dwarf_Fde * return_fde, + Dwarf_Error *error)\fP +.DE +When it succeeds, +\f(CWdwarf_get_fde_for_die()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_fde\fP +to +a \f(CWDwarf_Fde\fP +descriptor representing frame information for the given \f(CWdie\fP. It +looks for the \f(CWDW_AT_MIPS_fde\fP attribute in the given \f(CWdie\fP. +If it finds it, is uses the value of the attribute as the offset in +the .debug_frame section where the FDE begins. +If there is no \f(CWDW_AT_MIPS_fde\fP it returns \f(CWDW_DLV_NO_ENTRY\fP. +If there is an error it returns \f(CWDW_DLV_ERROR\fP. + +.H 4 "dwarf_get_fde_range()" +.DS +\f(CWint dwarf_get_fde_range( + Dwarf_Fde fde, + Dwarf_Addr *low_pc, + Dwarf_Unsigned *func_length, + Dwarf_Ptr *fde_bytes, + Dwarf_Unsigned *fde_byte_length, + Dwarf_Off *cie_offset, + Dwarf_Signed *cie_index, + Dwarf_Off *fde_offset, + Dwarf_Error *error);\fP +.DE +On success, +\f(CWdwarf_get_fde_range()\fP returns +\f(CWDW_DLV_OK\fP. +The location pointed to by \f(CWlow_pc\fP is set to the low pc value for +this function. +The location pointed to by \f(CWfunc_length\fP is +set to the length of the function in bytes. +This is essentially the +length of the text section for the function. +The location pointed +to by \f(CWfde_bytes\fP is set to the address where the FDE begins +in the .debug_frame section. +The location pointed to by +\f(CWfde_byte_length\fP is set to the length in bytes of the portion +of .debug_frame for this FDE. +This is the same as the value returned +by \f(CWdwarf_get_fde_range\fP. +The location pointed to by +\f(CWcie_offset\fP is set to the offset in the .debug_frame section +of the CIE used by this FDE. +The location pointed to by \f(CWcie_index\fP +is set to the index of the CIE used by this FDE. +The index is the +index of the CIE in the list pointed to by \f(CWcie_data\fP as set +by the function \f(CWdwarf_get_fde_list()\fP. +However, if the function +\f(CWdwarf_get_fde_for_die()\fP was used to obtain the given \f(CWfde\fP, +this index may not be correct. +The location pointed to by +\f(CWfde_offset\fP is set to the offset of the start of this FDE in +the .debug_frame section. +\f(CWdwarf_get_fde_range()\fP returns \f(CWDW_DLV_ERROR\fP on error. + +.H 4 "dwarf_get_cie_info()" +.DS +\f(CWint dwarf_get_cie_info( + Dwarf_Cie cie, + Dwarf_Unsigned *bytes_in_cie, + Dwarf_Small *version, + char **augmenter, + Dwarf_Unsigned *code_alignment_factor, + Dwarf_Signed *data_alignment_factor, + Dwarf_Half *return_address_register_rule, + Dwarf_Ptr *initial_instructions, + Dwarf_Unsigned *initial_instructions_length, + Dwarf_Error *error);\fP +.DE +\f(CWdwarf_get_cie_info()\fP is primarily for Internal-level Interface +consumers. +If successful, +it returns +\f(CWDW_DLV_OK\fP and sets \f(CW*bytes_in_cie\fP to +the number of bytes in the portion of the +frames section for the CIE represented by the given \f(CWDwarf_Cie\fP +descriptor, \f(CWcie\fP. +The other fields are directly taken from +the cie and returned, via the pointers to the caller. +It returns \f(CWDW_DLV_ERROR\fP on error. + +.H 4 "dwarf_get_fde_instr_bytes()" +.DS +\f(CWint dwarf_get_fde_instr_bytes( + Dwarf_Fde fde, + Dwarf_Ptr *outinstrs, + Dwarf_Unsigned *outlen, + Dwarf_Error *error);\fP +.DE +\f(CWdwarf_get_fde_instr_bytes()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*outinstrs\fP to +a pointer to a set of bytes which are the +actual frame instructions for this fde. +It also sets \f(CW*outlen\fP to the length, in +bytes, of the frame instructions. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. +The intent is to allow low-level consumers like a dwarf-dumper +to print the bytes in some fashion. +The memory pointed to by \f(CWoutinstrs\fP +must not be changed and there +is nothing to free. + +.H 4 "dwarf_get_fde_info_for_reg()" +This interface is suitable for DWARF2 but is not +sufficient for DWARF3. See \f(CWint dwarf_get_fde_info_for_reg3\fP. +.DS +\f(CWint dwarf_get_fde_info_for_reg( + Dwarf_Fde fde, + Dwarf_Half table_column, + Dwarf_Addr pc_requested, + Dwarf_Signed *offset_relevant, + Dwarf_Signed *register_num, + Dwarf_Signed *offset, + Dwarf_Addr *row_pc, + Dwarf_Error *error);\fP +.DE +\f(CWdwarf_get_fde_info_for_reg()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*offset_relevant\fP to +non-zero if the offset is relevant for the +row specified by \f(CWpc_requested\fP and column specified by +\f(CWtable_column\fP, for the FDE specified by \f(CWfde\fP. +The +intent is to return the rule for the given pc value and register. +The location pointed to by \f(CWregister_num\fP is set to the register +value for the rule. +The location pointed to by \f(CWoffset\fP +is set to the offset value for the rule. +If offset is not relevant for this rule, \f(CW*offset_relevant\fP is +set to zero. +Since more than one pc +value will have rows with identical entries, the user may want to +know the earliest pc value after which the rules for all the columns +remained unchanged. +Recall that in the virtual table that the frame information +represents there may be one or more table rows with identical data +(each such table row at a different pc value). +Given a \f(CWpc_requested\fP which refers to a pc in such a group +of identical rows, +the location pointed to by \f(CWrow_pc\fP is set +to the lowest pc value +within the group of identical rows. +The value put in \f(CW*register_num\fP any of the +\f(CWDW_FRAME_*\fP table columns values specified in \f(CWlibdwarf.h\fP +or \f(CWdwarf.h\fP. + +\f(CWdwarf_get_fde_info_for_reg\fP returns \f(CWDW_DLV_ERROR\fP if there is an error. + +It is usable with either +\f(CWdwarf_get_fde_n()\fP or \f(CWdwarf_get_fde_at_pc()\fP. + +.H 4 "dwarf_get_fde_info_for_all_regs()" +.DS +\f(CWint dwarf_get_fde_info_for_all_regs( + Dwarf_Fde fde, + Dwarf_Addr pc_requested, + Dwarf_Regtable *reg_table, + Dwarf_Addr *row_pc, + Dwarf_Error *error);\fP +.DE +\f(CWdwarf_get_fde_info_for_all_regs()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*reg_table\fP for the row specified by +\f(CWpc_requested\fP for the FDE specified by \f(CWfde\fP. +.P +The intent is +to return the rules for decoding all the registers, given a pc value. +\f(CWreg_table\fP is an array of rules, one for each register specified in +\f(CWdwarf.h\fP. The rule for each register contains three items - +\f(CWdw_regnum\fP which denotes the register value for that rule, +\f(CWdw_offset\fP which denotes the offset value for that rule and +\f(CWdw_offset_relevant\fP which is set to zero if offset is not relevant +for that rule. See \f(CWdwarf_get_fde_info_fo_reg()\fP for a description +of \f(CWrow_pc\fP. +.P +\f(CWdwarf_get_fde_info_for_all_regs\fP returns \f(CWDW_DLV_ERROR\fP if there is an error. +.P +\f(CWint dwarf_get_fde_info_for_all_regs\fP is SGI/MIPS specific. + + +.H 4 "dwarf_set_frame_rule_table_size()" +.P +This allows consumers to set the size of the (internal to libdwarf) +rule table. It should be at least as large as the +number of real registers in the ABI which is to be read in +for the dwarf_get_fde_info_for_reg3() or dwarf_get_fde_info_for_all_regs3() +functions to work properly. +It must be less than the marker values +DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL, DW_FRAME_CFA_COL3. +.P +.DS +\f(CWDwarf_Half +dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, + Dwarf_Half value);\fP + +.DE +\f(CWddwarf_set_frame_rule_table_size()\fP sets the +value \f(CWvalue\fP as the size of libdwarf-internal +rules tables of \f(CWdbg\fP. +The function returns +the previous value of the rules table size setting (taken from the +\f(CWdbg\fP structure). + +.H 4 "dwarf_set_frame_rule_inital_value()" +This allows consumers to set the initial value +for rows in the frame tables. By default it +is taken from libdwarf.h and is DW_FRAME_REG_INITIAL_VALUE +(which itself is either DW_FRAME_SAME_VAL or DW_FRAME_UNDEFINED_VAL). +The MIPS/IRIX default is DW_FRAME_SAME_VAL. +Comsumer code should set this appropriately and for +many architectures (but probably not MIPS) DW_FRAME_UNDEFINED_VAL is an +appropriate setting. +.DS +\f(CWDwarf_Half +dwarf_set_frame_rule_inital_value(Dwarf_Debug dbg, + Dwarf_Half value);\fP + +.DE +\f(CWdwarf_set_frame_rule_inital_value()\fP sets the +value \f(CWvalue\fP as the initial value for this \f(CWdbg\fP +when initializing rules tables. The function returns +the previous value of the initial setting (taken from the +\f(CWdbg\fP structure). + + + +.H 4 "dwarf_get_fde_info_for_reg3()" +This interface is suitable for DWARF3 and DWARF2. +It returns the values for a particular real register +(Not for the CFA register, see dwarf_get_fde_info_for_cfa_reg3() +below). +.DS +\f(CWint dwarf_get_fde_info_for_reg3( + Dwarf_Fde fde, + Dwarf_Half table_column, + Dwarf_Addr pc_requested, + Dwarf_Small *value_type, + Dwarf_Signed *offset_relevant, + Dwarf_Signed *register_num, + Dwarf_Signed *offset_or_block_len, + Dwarf_Ptr *block_ptr, + Dwarf_Addr *row_pc, + Dwarf_Error *error);\fP +.DE +\f(CWdwarf_get_fde_info_for_re3()\fP returns +\f(CWDW_DLV_OK\fP on success. +It sets \f(CW*value_type\fP +to one of DW_EXPR_OFFSET (0), +DW_EXPR_VAL_OFFSET(1), DW_EXPR_EXPRESSION(2) or +DW_EXPR_VAL_EXPRESSION(3). +On call, \f(CWtable_column\fP must be set to the +register number of a real register. Not +the cfa 'register' or DW_FRAME_SAME_VALUE or +DW_FRAME_UNDEFINED_VALUE. + + +if \f(CW*value_type\fP has the value DW_EXPR_OFFSET (0) then: +.in +4 +.P +It sets \f(CW*offset_relevant\fP to +non-zero if the offset is relevant for the +row specified by \f(CWpc_requested\fP and column specified by +\f(CWtable_column\fP or, for the FDE specified by \f(CWfde\fP. +In this case the \f(CW*register_num\fP will be set +to DW_FRAME_CFA_COL3. This is an offset(N) rule +as specified in the DWARF3/2 documents. +Adding the value of \f(CW*offset_or_block_len\fP +to the value of the CFA register gives the address +of a location holding the previous value of +register \f(CWtable_column\fP. + +.P +If offset is not relevant for this rule, \f(CW*offset_relevant\fP is +set to zero. \f(CW*register_num\fP will be set +to the number of the real register holding the value of +the \f(CWtable_column\fP register. +This is the register(R) rule as specifified in DWARF3/2 documents. +.P +The +intent is to return the rule for the given pc value and register. +The location pointed to by \f(CWregister_num\fP is set to the register +value for the rule. +The location pointed to by \f(CWoffset\fP +is set to the offset value for the rule. +Since more than one pc +value will have rows with identical entries, the user may want to +know the earliest pc value after which the rules for all the columns +remained unchanged. +Recall that in the virtual table that the frame information +represents there may be one or more table rows with identical data +(each such table row at a different pc value). +Given a \f(CWpc_requested\fP which refers to a pc in such a group +of identical rows, +the location pointed to by \f(CWrow_pc\fP is set +to the lowest pc value +within the group of identical rows. + +.in -4 + +.P +If \f(CW*value_type\fP has the value DW_EXPR_VAL_OFFSET (1) then: +.in +4 +This will be a val_offset(N) rule as specified in the +DWARF3/2 documents so \f(CW*offset_relevant\fP will +be non zero. +The calculation is identical to the DW_EXPR_OFFSET (0) +calculation with \f(CW*offset_relevant\fP non-zero, +but the value resulting is the actual \f(CWtable_column\fP +value (rather than the address where the value may be found). +.in -4 +.P +If \f(CW*value_type\fP has the value DW_EXPR_EXPRESSION (1) then: +.in +4 + \f(CW*offset_or_block_len\fP +is set to the length in bytes of a block of memory +with a DWARF expression in the block. +\f(CW*block_ptr\fP is set to point at the block of memory. +The consumer code should evaluate the block as +a DWARF-expression. The result is the address where +the previous value of the register may be found. +This is a DWARF3/2 expression(E) rule. +.in -4 +.P +If \f(CW*value_type\fP has the value DW_EXPR_VAL_EXPRESSION (1) then: +.in +4 +The calculation is exactly as for DW_EXPR_EXPRESSION (1) +but the result of the DWARF-expression evaluation is +the value of the \f(CWtable_column\fP (not +the address of the value). +This is a DWARF3/2 val_expression(E) rule. +.in -4 + +\f(CWdwarf_get_fde_info_for_reg\fP +returns \f(CWDW_DLV_ERROR\fP if there is an error and +if there is an error only the \f(CWerror\fP pointer is set, none +of the other output arguments are touched. + +It is usable with either +\f(CWdwarf_get_fde_n()\fP or \f(CWdwarf_get_fde_at_pc()\fP. + + +.H 4 "dwarf_get_fde_info_for_cfa_reg3()" +.DS + \f(CWint dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde, + Dwarf_Addr pc_requested, + Dwarf_Small * value_type, + Dwarf_Signed* offset_relevant, + Dwarf_Signed* register_num, + Dwarf_Signed* offset_or_block_len, + Dwarf_Ptr * block_ptr , + Dwarf_Addr * row_pc_out, + Dwarf_Error * error)\fP +.DE +.P +This is identical to \f(CWdwarf_get_fde_info_for_reg3()\fP +except the returned values are for the CFA rule. +So register number \f(CW*register_num\fP will be set +to a real register, not +DW_FRAME_CFA_COL3, DW_FRAME_SAME_VALUE, or +DW_FRAME_UNDEFINED_VALUE. + + + +.H 4 "dwarf_get_fde_info_for_all_regs3()" +.DS +\f(CWint dwarf_get_fde_info_for_all_regs3( + Dwarf_Fde fde, + Dwarf_Addr pc_requested, + Dwarf_Regtable3 *reg_table, + Dwarf_Addr *row_pc, + Dwarf_Error *error)\fP +.DE +\f(CWdwarf_get_fde_info_for_all_regs3()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*reg_table\fP +for the row specified by +\f(CWpc_requested\fP for the FDE specified by \f(CWfde\fP. +The intent is +to return the rules for decoding all the registers, given a pc +value. +\f(CWreg_table\fP is an array of rules, the +array size specifed by the caller. +plus a rule for the CFA. +The rule for the cfa returned in \f(CW*reg_table\fP +defines the CFA value at \f(CWpc_requested\fP +The rule for each +register contains several values that enable +the consumer to determine the previous value +of the register (see the earlier documentation of Dwarf_Regtable3). +\f(CWdwarf_get_fde_info_for_reg3()\fP and +the Dwarf_Regtable3 documentation above for a description of +the values for each row. + +\f(CWdwarf_get_fde_info_for_all_regs\fP returns \f(CWDW_DLV_ERROR\fP if there is an error. + +It's up to the caller to allocate space for +\f(CW*reg_table\fP and initialize it properly. + + + +.H 4 "dwarf_get_fde_n()" +.DS +\f(CWint dwarf_get_fde_n( + Dwarf_Fde *fde_data, + Dwarf_Unsigned fde_index, + Dwarf_Fde *returned_fde + Dwarf_Error *error)\fP +.DE +\f(CWdwarf_get_fde_n()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CWreturned_fde\fP to +the \f(CWDwarf_Fde\fP descriptor whose +index is \f(CWfde_index\fP in the table of \f(CWDwarf_Fde\fP descriptors +pointed to by \fPfde_data\fP. +The index starts with 0. +Returns \f(CWDW_DLV_NO_ENTRY\fP if the index does not +exist in the table of \f(CWDwarf_Fde\fP +descriptors. +Returns \f(CWDW_DLV_ERROR\fP if there is an error. +This function cannot be used unless +the block of \f(CWDwarf_Fde\fP descriptors has been created by a call to +\f(CWdwarf_get_fde_list()\fP. + +.H 4 "dwarf_get_fde_at_pc()" +.DS +\f(CWint dwarf_get_fde_at_pc( + Dwarf_Fde *fde_data, + Dwarf_Addr pc_of_interest, + Dwarf_Fde *returned_fde, + Dwarf_Addr *lopc, + Dwarf_Addr *hipc, + Dwarf_Error *error)\fP +.DE +\f(CWdwarf_get_fde_at_pc()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CWreturned_fde\fP to +a \f(CWDwarf_Fde\fP descriptor +for a function which contains the pc value specified by \f(CWpc_of_interest\fP. +In addition, it sets the locations pointed to +by \f(CWlopc\fP and \f(CWhipc\fP to the low address and the high address +covered by this FDE, respectively. +It returns \f(CWDW_DLV_ERROR\fP on error. +It returns \f(CWDW_DLV_NO_ENTRY\fP +if \f(CWpc_of_interest\fP is not in any of the +FDEs represented by the block of \f(CWDwarf_Fde\fP descriptors pointed +to by \f(CWfde_data\fP. +This function cannot be used unless +the block of \f(CWDwarf_Fde\fP descriptors has been created by a call to +\f(CWdwarf_get_fde_list()\fP. + +.H 4 "dwarf_expand_frame_instructions()" +.DS +\f(CWint dwarf_expand_frame_instructions( + Dwarf_Debug dbg, + Dwarf_Ptr instruction, + Dwarf_Unsigned i_length, + Dwarf_Frame_Op **returned_op_list, + Dwarf_Signed * returned_op_count, + Dwarf_Error *error);\fP +.DE +\f(CWdwarf_expand_frame_instructions()\fP is a High-level interface +function which expands a frame instruction byte stream into an +array of \f(CWDwarf_Frame_Op\fP structures. +To indicate success, it returns \f(CWDW_DLV_OK\fP. +The address where +the byte stream begins is specified by \f(CWinstruction\fP, and +the length of the byte stream is specified by \f(CWi_length\fP. +The location pointed to by \f(CWreturned_op_list\fP is set to +point to a table of +\f(CWreturned_op_count\fP +pointers to \f(CWDwarf_Frame_Op\fP which +contain the frame instructions in the byte stream. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. +After a successful return, the +array of structures should be freed using +\f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_FRAME_BLOCK\fP +(when they are no longer of interest). + +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Frame_Op *frameops; +Dwarf_Ptr instruction; +Dwarf_Unsigned len; +int res; + +res = expand_frame_instructions(dbg,instruction,len, &frameops,&cnt, &error); +if (res == DW_DLV_OK) { + + for (i = 0; i < cnt; ++i) { + /* use frameops[i] */ + } + dwarf_dealloc(dbg, frameops, DW_DLA_FRAME_BLOCK); +}\fP +.DE +.in -2 +.H 4 "dwarf_get_fde_exception_info()" +.DS +\f(CWint dwarf_get_fde_exception_info( + Dwarf_Fde fde, + Dwarf_Signed * offset_into_exception_tables, + Dwarf_Error * error); +.DE +\f(CWdwarf_get_fde_exception_info()\fP is an IRIX specific +function which returns an exception table signed offset +thru \f(CWoffset_into_exception_tables\fP. +The function never returns \f(CWDW_DLV_NO_ENTRY\fP. +If \f(CWDW_DLV_NO_ENTRY\fP is NULL the function returns +\f(CWDW_DLV_ERROR\fP. +For non-IRIX objects the offset returned will always be zero. +For non-C++ objects the offset returned will always be zero. +The meaning of the offset and the content of the tables +is not defined in this document. +The applicable CIE augmentation string (see above) +determines whether the value returned has meaning. + +.H 2 "Location Expression Evaluation" + +An "interpreter" which evaluates a location expression +is required in any debugger. There is no interface defined +here at this time. + +.P +One problem with defining an interface is that operations are +machine dependent: they depend on the interpretation of +register numbers and the methods of getting values from the +environment the expression is applied to. + +.P +It would be desirable to specify an interface. + +.H 3 "Location List Internal-level Interface" + +.H 4 "dwarf_get_loclist_entry()" +.DS +\f(CWint dwarf_get_loclist_entry( + Dwarf_Debug dbg, + Dwarf_Unsigned offset, + Dwarf_Addr *hipc_offset, + Dwarf_Addr *lopc_offset, + Dwarf_Ptr *data, + Dwarf_Unsigned *entry_len, + Dwarf_Unsigned *next_entry, + Dwarf_Error *error)\fP +.DE +The function reads +a location list entry starting at \f(CWoffset\fP and returns +through pointers (when successful) +the high pc \f(CWhipc_offset\fP, low pc +\f(CWlopc_offset\fP, a pointer to the location description data +\f(CWdata\fP, the length of the location description data +\f(CWentry_len\fP, and the offset of the next location description +entry \f(CWnext_entry\fP. +\f(CWdwarf_dwarf_get_loclist_entry()\fP returns +\f(CWDW_DLV_OK\fP if successful. +\f(CWDW_DLV_NO_ENTRY\fP is returned when the offset passed +in is beyond the end of the .debug_loc section (expected if +you start at offset zero and proceed thru all the entries). +\f(CWDW_DLV_ERROR\fP is returned on error. +.P +The \f(CWhipc_offset\fP, +low pc \f(CWlopc_offset\fP are offsets from the beginning of the +current procedure, not genuine pc values. +.in +2 +.DS +\f(CW +/* Looping thru the dwarf_loc section finding loclists: + an example. */ +int res; +Dwarf_Unsigned next_entry; +Dwarf_unsigned offset=0; +Dwarf_Addr hipc_off; +Dwarf_Addr lopc_off; +Dwarf_Ptr data; +Dwarf_Unsigned entry_len; +Dwarf_Unsigned next_entry; +Dwarf_Error err; + + for(;;) { + res = dwarf_get_loclist_entry(dbg,newoffset,&hipc_off, + &lowpc_off, &data, &entry_len,&next_entry,&err); + if (res == DW_DLV_OK) { + /* A valid entry. */ + newoffset = next_entry; + continue; + } else if (res ==DW_DLV_NO_ENTRY) { + /* Done! */ + break; + } else { + /* Error! */ + break; + } + + + } +}\fP +.DE +.in -2 + + +.H 2 "Abbreviations access" +These are Internal-level Interface functions. +Debuggers can ignore this. + +.H 3 "dwarf_get_abbrev()" +.DS +\f(CWint dwarf_get_abbrev( + Dwarf_Debug dbg, + Dwarf_Unsigned offset, + Dwarf_Abbrev *returned_abbrev, + Dwarf_Unsigned *length, + Dwarf_Unsigned *attr_count, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_get_abbrev()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*returned_abbrev\fP to +\f(CWDwarf_Abbrev\fP +descriptor for an abbreviation at offset \f(CW*offset\fP in the abbreviations +section (i.e .debug_abbrev) on success. +The user is responsible for making sure that +a valid abbreviation begins at \f(CWoffset\fP in the abbreviations section. +The location pointed to by \f(CWlength\fP +is set to the length in bytes of the abbreviation in the abbreviations +section. +The location pointed to by \f(CWattr_count\fP is set to the +number of attributes in the abbreviation. +An abbreviation entry with a +length of 1 is the 0 byte of the last abbreviation entry of a compilation +unit. +\f(CWdwarf_get_abbrev()\fP returns \f(CWDW_DLV_ERROR\fP on error. +If the call succeeds, the storage pointed to +by \f(CW*returned_abbrev\fP +should be free'd, using \f(CWdwarf_dealloc()\fP with the +allocation type \f(CWDW_DLA_ABBREV\fP when no longer needed. + + +.H 3 "dwarf_get_abbrev_tag()" +.DS +\f(CWint dwarf_get_abbrev_tag( + Dwarf_abbrev abbrev, + Dwarf_Half *return_tag, + Dwarf_Error *error);\fP +.DE +If successful, +\f(CWdwarf_get_abbrev_tag()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_tag\fP to +the \fItag\fP of +the given abbreviation. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 3 "dwarf_get_abbrev_code()" +.DS +\f(CWint dwarf_get_abbrev_code( + Dwarf_abbrev abbrev, + Dwarf_Unsigned *return_code, + Dwarf_Error *error);\fP +.DE +If successful, +\f(CWdwarf_get_abbrev_code()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*return_code\fP to +the abbreviation code of +the given abbreviation. +It returns \f(CWDW_DLV_ERROR\fP on error. +It never returns \f(CWDW_DLV_NO_ENTRY\fP. + +.H 3 "dwarf_get_abbrev_children_flag()" +.DS +\f(CWint dwarf_get_abbrev_children_flag( + Dwarf_Abbrev abbrev, + Dwarf_Signed *returned_flag, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_get_abbrev_children_flag()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CWreturned_flag\fP to +\f(CWDW_children_no\fP (if the given abbreviation indicates that +a die with that abbreviation has no children) or +\f(CWDW_children_yes\fP (if the given abbreviation indicates that +a die with that abbreviation has a child). +It returns \f(CWDW_DLV_ERROR\fP on error. + +.H 3 "dwarf_get_abbrev_entry()" +.DS +\f(CWint dwarf_get_abbrev_entry( + Dwarf_Abbrev abbrev, + Dwarf_Signed index, + Dwarf_Half *attr_num, + Dwarf_Signed *form, + Dwarf_Off *offset, + Dwarf_Error *error)\fP + +.DE +If successful, +\f(CWdwarf_get_abbrev_entry()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*attr_num\fP to the attribute code of +the attribute +whose index is specified by \f(CWindex\fP in the given abbreviation. +The index starts at 0. +The location pointed to by \f(CWform\fP is set +to the form of the attribute. +The location pointed to by \f(CWoffset\fP +is set to the byte offset of the attribute in the abbreviations section. +It returns \f(CWDW_DLV_NO_ENTRY\fP if the index specified is outside +the range of attributes in this abbreviation. +It returns \f(CWDW_DLV_ERROR\fP on error. + +.H 2 "String Section Operations" +The .debug_str section contains only strings. Debuggers need +never use this interface: it is only for debugging problems with +the string section itself. + +.H 3 "dwarf_get_str()" +.DS +\f(CWint dwarf_get_str( + Dwarf_Debug dbg, + Dwarf_Off offset, + char **string, + Dwarf_Signed *returned_str_len, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_get_str()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*returned_str_len\fP to +the length of +the string, not counting the null terminator, that begins at the offset +specified by \f(CWoffset\fP in the .debug_str section. +The location +pointed to by \f(CWstring\fP is set to a pointer to this string. +The next string in the .debug_str +section begins at the previous \f(CWoffset\fP + 1 + \f(CW*returned_str_len\fP. +A zero-length string is NOT the end of the section. +If there is no .debug_str section, \f(CWDW_DLV_NO_ENTRY\fP is returned. +If there is an error, \f(CWDW_DLV_ERROR\fP is returned. +If we are at the end of the section (that is, \f(CWoffset\fP +is one past the end of the section) \f(CWDW_DLV_NO_ENTRY\fP is returned. +If the \f(CWoffset\fP is some other too-large value then +\f(CWDW_DLV_ERROR\fP is returned. + +.H 2 "Address Range Operations" +These functions provide information about address ranges. Address +ranges map ranges of pc values to the corresponding compilation-unit +die that covers the address range. + +.H 3 "dwarf_get_aranges()" +.DS +\f(CWint dwarf_get_aranges( + Dwarf_Debug dbg, + Dwarf_Arange **aranges, + Dwarf_Signed * returned_arange_count, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_get_aranges()\fP returns +\f(CWDW_DLV_OK\fP and sets \f(CW*returned_arange_count\fP to +the count of the +number of address ranges in the .debug_aranges section. +It sets +\f(CW*aranges\fP to point to a block of \f(CWDwarf_Arange\fP +descriptors, one for each address range. +It returns \f(CWDW_DLV_ERROR\fP on error. +It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no .debug_aranges +section. + +.in +2 +.DS +\f(CWDwarf_Signed cnt; +Dwarf_Arange *arang; +int res; + +res = dwarf_get_aranges(dbg, &arang,&cnt, &error); +if (res == DW_DLV_OK) { + + for (i = 0; i < cnt; ++i) { + /* use arang[i] */ + dwarf_dealloc(dbg, arang[i], DW_DLA_ARANGE); + } + dwarf_dealloc(dbg, arang, DW_DLA_LIST); +}\fP +.DE +.in -2 + + +.DS +\f(CWint dwarf_get_arange( + Dwarf_Arange *aranges, + Dwarf_Unsigned arange_count, + Dwarf_Addr address, + Dwarf_Arange *returned_arange, + Dwarf_Error *error);\fP +.DE +The function \f(CWdwarf_get_arange()\fP takes as input a pointer +to a block of \f(CWDwarf_Arange\fP pointers, and a count of the +number of descriptors in the block. +It then searches for the +descriptor that covers the given \f(CWaddress\fP. +If it finds +one, it returns +\f(CWDW_DLV_OK\fP and sets \f(CW*returned_arange\fP to +the descriptor. +It returns \f(CWDW_DLV_ERROR\fP on error. +It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no .debug_aranges +entry covering that address. + + +.H 3 "dwarf_get_cu_die_offset()" +.DS +\f(CWint dwarf_get_cu_die_offset( + Dwarf_Arange arange, + Dwarf_Off *returned_cu_die_offset, + Dwarf_Error *error);\fP +.DE +The function \f(CWdwarf_get_cu_die_offset()\fP takes a +\f(CWDwarf_Arange\fP descriptor as input, and +if successful returns +\f(CWDW_DLV_OK\fP and sets \f(CW*returned_cu_die_offset\fP to +the offset +in the .debug_info section of the compilation-unit DIE for the +compilation-unit represented by the given address range. +It returns \f(CWDW_DLV_ERROR\fP on error. + +.H 3 "dwarf_get_arange_cu_header_offset()" +.DS +\f(CWint dwarf_get_arange_cu_header_offset( + Dwarf_Arange arange, + Dwarf_Off *returned_cu_header_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_get_arange_cu_header_offset()\fP takes a +\f(CWDwarf_Arange\fP descriptor as input, and +if successful returns +\f(CWDW_DLV_OK\fP and sets \f(CW*returned_cu_header_offset\fP to +the offset +in the .debug_info section of the compilation-unit header for the +compilation-unit represented by the given address range. +It returns \f(CWDW_DLV_ERROR\fP on error. + +This function added Rev 1.45, June, 2001. + +This function is declared as 'optional' in libdwarf.h +on IRIX systems so the _MIPS_SYMBOL_PRESENT +predicate may be used at run time to determine if the version of +libdwarf linked into an application has this function. + + + +.H 3 "dwarf_get_arange_info()" +.DS +\f(CWint dwarf_get_arange_info( + Dwarf_Arange arange, + Dwarf_Addr *start, + Dwarf_Unsigned *length, + Dwarf_Off *cu_die_offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_get_arange_info()\fP returns +\f(CWDW_DLV_OK\fP +and +stores the starting value of the address range in the location pointed +to by \f(CWstart\fP, the length of the address range in the location +pointed to by \f(CWlength\fP, and the offset in the .debug_info section +of the compilation-unit DIE for the compilation-unit represented by the +address range. +It returns \f(CWDW_DLV_ERROR\fP on error. + +.H 2 "General Low Level Operations" +This function is low-level and intended for use only +by programs such as dwarf-dumpers. + +.H 3 "dwarf_get_address_size()" +.DS +\f(CWint dwarf_get_address_size(Dwarf_Debug dbg, + Dwarf_Half *addr_size, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_get_address_size()\fP +returns \f(CWDW_DLV_OK\fP on success and sets +the \f(CW*addr_size\fP +to the size in bytes of an address. +In case of error, it returns \f(CWDW_DLV_ERROR\fP +and does not set \f(CW*addr_size\fP. + + +.H 2 "Utility Operations" +These functions aid in the management of errors encountered when using +functions in the \fIlibdwarf\fP library and releasing memory allocated +as a result of a \fIlibdwarf\fP operation. + +.H 3 "dwarf_errno()" +.DS +\f(CWDwarf_Unsigned dwarf_errno( + Dwarf_Error error)\fP +.DE +The function \f(CWdwarf_errno()\fP returns the error number corresponding +to the error specified by \f(CWerror\fP. + +.H 3 "dwarf_errmsg()" +.DS +\f(CWconst char* dwarf_errmsg( + Dwarf_Error error)\fP +.DE +The function \f(CWdwarf_errmsg()\fP returns a pointer to a +null-terminated error message string corresponding to the error specified by +\f(CWerror\fP. +The string returned by \f(CWdwarf_errmsg()\fP +should not be deallocated using \f(CWdwarf_dealloc()\fP. + +.P +The set of errors +enumerated in Figure \n(aX below were defined in Dwarf 1. +These errors are not used by the current implementation +of Dwarf 2. +.DS +.TS +center box, tab(:); +lfB lfB +l l. +SYMBOLIC NAME:DESCRIPTION +_ +DW_DLE_NE:No error (0) +DW_DLE_VMM:Version of DWARF information newer than libdwarf +DW_DLE_MAP:Memory map failure +DW_DLE_LEE:Propagation of libelf error +DW_DLE_NDS:No debug section +DW_DLE_NLS:No line section +DW_DLE_ID:Requested information not associated with descriptor +DW_DLE_IOF:I/O failure +DW_DLE_MAF:Memory allocation failure +DW_DLE_IA:Invalid argument +DW_DLE_MDE:Mangled debugging entry +DW_DLE_MLE:Mangled line number entry +DW_DLE_FNO:File descriptor does not refer to an open file +DW_DLE_FNR:File is not a regular file +DW_DLE_FWA:File is opened with wrong access +DW_DLE_NOB:File is not an object file +DW_DLE_MOF:Mangled object file header +DW_DLE_EOLL:End of location list entries +DW_DLE_NOLL:No location list section +DW_DLE_BADOFF:Invalid offset +DW_DLE_EOS:End of section +DW_DLE_ATRUNC:Abbreviations section appears truncated +DW_DLE_BADBITC:Address size passed to dwarf bad +.TE +.FG "List of Dwarf Error Codes" +.DE + +The set of errors returned by SGI \f(CWLibdwarf\fP functions +is listed below. +Some of the errors are SGI specific. + +.DS +.TS +center box, tab(:); +lfB lfB +l l. +SYMBOLIC NAME:DESCRIPTION +_ +DW_DLE_DBG_ALLOC:Could not allocate Dwarf_Debug struct +DW_DLE_FSTAT_ERROR:Error in fstat()-ing object +DW_DLE_FSTAT_MODE_ERROR:Error in mode of object file +DW_DLE_INIT_ACCESS_WRONG:Incorrect access to dwarf_init() +DW_DLE_ELF_BEGIN_ERROR:Error in elf_begin() on object +DW_DLE_ELF_GETEHDR_ERROR:Error in elf_getehdr() on object +DW_DLE_ELF_GETSHDR_ERROR:Error in elf_getshdr() on object +DW_DLE_ELF_STRPTR_ERROR:Error in elf_strptr() on object +DW_DLE_DEBUG_INFO_DUPLICATE:Multiple .debug_info sections +DW_DLE_DEBUG_INFO_NULL:No data in .debug_info section +DW_DLE_DEBUG_ABBREV_DUPLICATE:Multiple .debug_abbrev sections +DW_DLE_DEBUG_ABBREV_NULL:No data in .debug_abbrev section +DW_DLE_DEBUG_ARANGES_DUPLICATE:Multiple .debug_arange sections +DW_DLE_DEBUG_ARANGES_NULL:No data in .debug_arange section +DW_DLE_DEBUG_LINE_DUPLICATE:Multiple .debug_line sections +DW_DLE_DEBUG_LINE_NULL:No data in .debug_line section +DW_DLE_DEBUG_LOC_DUPLICATE:Multiple .debug_loc sections +DW_DLE_DEBUG_LOC_NULL:No data in .debug_loc section +DW_DLE_DEBUG_MACINFO_DUPLICATE:Multiple .debug_macinfo sections +DW_DLE_DEBUG_MACINFO_NULL:No data in .debug_macinfo section +DW_DLE_DEBUG_PUBNAMES_DUPLICATE:Multiple .debug_pubnames sections +DW_DLE_DEBUG_PUBNAMES_NULL:No data in .debug_pubnames section +DW_DLE_DEBUG_STR_DUPLICATE:Multiple .debug_str sections +DW_DLE_DEBUG_STR_NULL:No data in .debug_str section +DW_DLE_CU_LENGTH_ERROR:Length of compilation-unit bad +DW_DLE_VERSION_STAMP_ERROR:Incorrect Version Stamp +DW_DLE_ABBREV_OFFSET_ERROR:Offset in .debug_abbrev bad +DW_DLE_ADDRESS_SIZE_ERROR:Size of addresses in target bad +DW_DLE_DEBUG_INFO_PTR_NULL:Pointer into .debug_info in DIE null +DW_DLE_DIE_NULL:Null Dwarf_Die +DW_DLE_STRING_OFFSET_BAD:Offset in .debug_str bad +DW_DLE_DEBUG_LINE_LENGTH_BAD:Length of .debug_line segment bad +DW_DLE_LINE_PROLOG_LENGTH_BAD:Length of .debug_line prolog bad +DW_DLE_LINE_NUM_OPERANDS_BAD:Number of operands to line instr bad +DW_DLE_LINE_SET_ADDR_ERROR:Error in DW_LNE_set_address instruction +DW_DLE_LINE_EXT_OPCODE_BAD:Error in DW_EXTENDED_OPCODE instruction +DW_DLE_DWARF_LINE_NULL:Null Dwarf_line argument +DW_DLE_INCL_DIR_NUM_BAD:Error in included directory for given line +DW_DLE_LINE_FILE_NUM_BAD:File number in .debug_line bad +DW_DLE_ALLOC_FAIL:Failed to allocate required structs +DW_DLE_DBG_NULL:Null Dwarf_Debug argument +DW_DLE_DEBUG_FRAME_LENGTH_BAD:Error in length of frame +DW_DLE_FRAME_VERSION_BAD:Bad version stamp for frame +DW_DLE_CIE_RET_ADDR_REG_ERROR:Bad register specified for return address +DW_DLE_FDE_NULL:Null Dwarf_Fde argument +DW_DLE_FDE_DBG_NULL:No Dwarf_Debug associated with FDE +DW_DLE_CIE_NULL:Null Dwarf_Cie argument +DW_DLE_CIE_DBG_NULL:No Dwarf_Debug associated with CIE +DW_DLE_FRAME_TABLE_COL_BAD:Bad column in frame table specified +.TE +.FG "List of Dwarf 2 Error Codes (continued)" +.DE + +.DS +.TS +center box, tab(:); +lfB lfB +l l. +SYMBOLIC NAME:DESCRIPTION +_ +DW_DLE_PC_NOT_IN_FDE_RANGE:PC requested not in address range of FDE +DW_DLE_CIE_INSTR_EXEC_ERROR:Error in executing instructions in CIE +DW_DLE_FRAME_INSTR_EXEC_ERROR:Error in executing instructions in FDE +DW_DLE_FDE_PTR_NULL:Null Pointer to Dwarf_Fde specified +DW_DLE_RET_OP_LIST_NULL:No location to store pointer to Dwarf_Frame_Op +DW_DLE_LINE_CONTEXT_NULL:Dwarf_Line has no context +DW_DLE_DBG_NO_CU_CONTEXT:dbg has no CU context for dwarf_siblingof() +DW_DLE_DIE_NO_CU_CONTEXT:Dwarf_Die has no CU context +DW_DLE_FIRST_DIE_NOT_CU:First DIE in CU not DW_TAG_compilation_unit +DW_DLE_NEXT_DIE_PTR_NULL:Error in moving to next DIE in .debug_info +DW_DLE_DEBUG_FRAME_DUPLICATE:Multiple .debug_frame sections +DW_DLE_DEBUG_FRAME_NULL:No data in .debug_frame section +DW_DLE_ABBREV_DECODE_ERROR:Error in decoding abbreviation +DW_DLE_DWARF_ABBREV_NULL:Null Dwarf_Abbrev specified +DW_DLE_ATTR_NULL:Null Dwarf_Attribute specified +DW_DLE_DIE_BAD:DIE bad +DW_DLE_DIE_ABBREV_BAD:No abbreviation found for code in DIE +DW_DLE_ATTR_FORM_BAD:Inappropriate attribute form for attribute +DW_DLE_ATTR_NO_CU_CONTEXT:No CU context for Dwarf_Attribute struct +DW_DLE_ATTR_FORM_SIZE_BAD:Size of block in attribute value bad +DW_DLE_ATTR_DBG_NULL:No Dwarf_Debug for Dwarf_Attribute struct +DW_DLE_BAD_REF_FORM:Inappropriate form for reference attribute +DW_DLE_ATTR_FORM_OFFSET_BAD:Offset reference attribute outside current CU +DW_DLE_LINE_OFFSET_BAD:Offset of lines for current CU outside .debug_line +DW_DLE_DEBUG_STR_OFFSET_BAD:Offset into .debug_str past its end +DW_DLE_STRING_PTR_NULL:Pointer to pointer into .debug_str NULL +DW_DLE_PUBNAMES_VERSION_ERROR:Version stamp of pubnames incorrect +DW_DLE_PUBNAMES_LENGTH_BAD:Read pubnames past end of .debug_pubnames +DW_DLE_GLOBAL_NULL:Null Dwarf_Global specified +DW_DLE_GLOBAL_CONTEXT_NULL:No context for Dwarf_Global given +DW_DLE_DIR_INDEX_BAD:Error in directory index read +DW_DLE_LOC_EXPR_BAD:Bad operator read for location expression +DW_DLE_DIE_LOC_EXPR_BAD:Expected block value for attribute not found +DW_DLE_OFFSET_BAD:Offset for next compilation-unit in .debug_info bad +DW_DLE_MAKE_CU_CONTEXT_FAIL:Could not make CU context +DW_DLE_ARANGE_OFFSET_BAD:Offset into .debug_info in .debug_aranges bad +DW_DLE_SEGMENT_SIZE_BAD:Segment size should be 0 for MIPS processors +DW_DLE_ARANGE_LENGTH_BAD:Length of arange section in .debug_arange bad +DW_DLE_ARANGE_DECODE_ERROR:Aranges do not end at end of .debug_aranges +DW_DLE_ARANGES_NULL:NULL pointer to Dwarf_Arange specified +DW_DLE_ARANGE_NULL:NULL Dwarf_Arange specified +DW_DLE_NO_FILE_NAME:No file name for Dwarf_Line struct +DW_DLE_NO_COMP_DIR:No Compilation directory for compilation-unit +DW_DLE_CU_ADDRESS_SIZE_BAD:CU header address size not match Elf class +DW_DLE_ELF_GETIDENT_ERROR:Error in elf_getident() on object +DW_DLE_NO_AT_MIPS_FDE:DIE does not have DW_AT_MIPS_fde attribute +DW_DLE_NO_CIE_FOR_FDE:No CIE specified for FDE +DW_DLE_DIE_ABBREV_LIST_NULL:No abbreviation for the code in DIE found +DW_DLE_DEBUG_FUNCNAMES_DUPLICATE:Multiple .debug_funcnames sections +DW_DLE_DEBUG_FUNCNAMES_NULL:No data in .debug_funcnames section +.TE +.FG "List of Dwarf 2 Error Codes (continued)" +.DE + +.DS +.TS +center box, tab(:); +lfB lfB +l l. +SYMBOLIC NAME:DESCRIPTION +_ +DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR:Version stamp in .debug_funcnames bad +DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD:Length error in reading .debug_funcnames +DW_DLE_FUNC_NULL:NULL Dwarf_Func specified +DW_DLE_FUNC_CONTEXT_NULL:No context for Dwarf_Func struct +DW_DLE_DEBUG_TYPENAMES_DUPLICATE:Multiple .debug_typenames sections +DW_DLE_DEBUG_TYPENAMES_NULL:No data in .debug_typenames section +DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR:Version stamp in .debug_typenames bad +DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD:Length error in reading .debug_typenames +DW_DLE_TYPE_NULL:NULL Dwarf_Type specified +DW_DLE_TYPE_CONTEXT_NULL:No context for Dwarf_Type given +DW_DLE_DEBUG_VARNAMES_DUPLICATE:Multiple .debug_varnames sections +DW_DLE_DEBUG_VARNAMES_NULL:No data in .debug_varnames section +DW_DLE_DEBUG_VARNAMES_VERSION_ERROR:Version stamp in .debug_varnames bad +DW_DLE_DEBUG_VARNAMES_LENGTH_BAD:Length error in reading .debug_varnames +DW_DLE_VAR_NULL:NULL Dwarf_Var specified +DW_DLE_VAR_CONTEXT_NULL:No context for Dwarf_Var given +DW_DLE_DEBUG_WEAKNAMES_DUPLICATE:Multiple .debug_weaknames section +DW_DLE_DEBUG_WEAKNAMES_NULL:No data in .debug_varnames section +DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR:Version stamp in .debug_varnames bad +DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD:Length error in reading .debug_weaknames +DW_DLE_WEAK_NULL:NULL Dwarf_Weak specified +DW_DLE_WEAK_CONTEXT_NULL:No context for Dwarf_Weak given +.TE +.FG "List of Dwarf 2 Error Codes" +.DE + +This list of errors is not necessarily complete; +additional errors +might be added when functionality to create debugging information +entries are added to \fIlibdwarf\fP and by the implementors of +\fIlibdwarf\fP to describe internal errors not addressed by the +above list. +Some of the above errors may be unused. +Errors may not have the same meaning in different implementations. + +.H 3 "dwarf_seterrhand()" +.DS +\f(CWDwarf_Handler dwarf_seterrhand( + Dwarf_Debug dbg, + Dwarf_Handler errhand)\fP +.DE +The function \f(CWdwarf_seterrhand()\fP replaces the error handler +(see \f(CWdwarf_init()\fP) with \f(CWerrhand\fP. The old error handler +is returned. This function is currently unimplemented. + +.H 3 "dwarf_seterrarg()" +.DS +\f(CWDwarf_Ptr dwarf_seterrarg( + Dwarf_Debug dbg, + Dwarf_Ptr errarg)\fP +.DE +The function \f(CWdwarf_seterrarg()\fP replaces the pointer to the +error handler communication area (see \f(CWdwarf_init()\fP) with +\f(CWerrarg\fP. A pointer to the old area is returned. This +function is currently unimplemented. + +.H 3 "dwarf_dealloc()" +.DS +\f(CWvoid dwarf_dealloc( + Dwarf_Debug dbg, + void* space, + Dwarf_Unsigned type)\fP +.DE +The function \f(CWdwarf_dealloc\fP frees the dynamic storage pointed +to by \f(CWspace\fP, and allocated to the given \f(CWDwarf_Debug\fP. +The argument \f(CWtype\fP is an integer code that specifies the allocation +type of the region pointed to by the \f(CWspace\fP. Refer to section +4 for details on \fIlibdwarf\fP memory management. + +.SK +.S +.TC 1 1 4 +.CS diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2.1.pdf Binary file tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2.1.pdf has changed diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2p.1.mm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2p.1.mm Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,2452 @@ +\." $Revision: 1.12 $ +\." $Date: 2002/01/14 23:40:11 $ +\." +\." +\." the following line may be removed if the ff ligature works on your machine +.lg 0 +\." set up heading formats +.ds HF 3 3 3 3 3 2 2 +.ds HP +2 +2 +1 +0 +0 +.nr Hs 5 +.nr Hb 5 +\." ============================================== +\." Put current date in the following at each rev +.ds vE rev 1.20, 4 Sep 2007 +\." ============================================== +\." ============================================== +.ds | | +.ds ~ ~ +.ds ' ' +.if t .ds Cw \&\f(CW +.if n .ds Cw \fB +.de Cf \" Place every other arg in Cw font, beginning with first +.if \\n(.$=1 \&\*(Cw\\$1\fP +.if \\n(.$=2 \&\*(Cw\\$1\fP\\$2 +.if \\n(.$=3 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP +.if \\n(.$=4 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4 +.if \\n(.$=5 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP +.if \\n(.$=6 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6 +.if \\n(.$=7 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP +.if \\n(.$=8 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8 +.if \\n(.$=9 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8\ +*(Cw +.. +.nr Cl 3 +.SA 1 +.TL +A Producer Library Interface to DWARF +.AF "" +.AU "David Anderson" +.PF "'\*(vE '- \\\\nP -''" +.AS 1 +This document describes an interface to a library of functions +to create DWARF debugging information entries and DWARF line number +information. It does not make recommendations as to how the functions +described in this document should be implemented nor does it +suggest possible optimizations. +.P +The document is oriented to creating DWARF version 2. +Support for creating DWARF3 is intended but such support +is not yet fully present. +.P +\*(vE +.AE +.MT 4 +.H 1 "INTRODUCTION" +This document describes an interface to \f(CWlibdwarf\fP, a +library of functions to provide creation of DWARF debugging information +records, DWARF line number information, DWARF address range and +pubnames information, weak names information, and DWARF frame description +information. + + +.H 2 "Copyright" +Copyright 1993-2006 Silicon Graphics, Inc. + +Copyright 2007 David Anderson. + +Permission is hereby granted to +copy or republish or use any or all of this document without +restriction except that when publishing more than a small amount +of the document +please acknowledge Silicon Graphics, Inc and David Anderson. + +This document is distributed in the hope that it would be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +.H 2 "Purpose and Scope" +The purpose of this document is to propose a library of functions to +create DWARF debugging information. Reading (consuming) of such records +is discussed in a separate document. + +The functions in this document have mostly been implemented at +Silicon Graphics +and are being used by the code generator to provide debugging information. +Some functions (and support for some extensions) were provided +by Sun Microsystems. + +.P +The focus of this document is the functional interface, +and as such, implementation and optimization issues are +intentionally ignored. + +.P +Error handling, error codes, and certain \f(CWLibdwarf\fP codes are discussed +in the "\fIA Consumer Library Interface to DWARF\fP", which should +be read (or at least skimmed) before reading this document. +.P +However the general style of functions here +in the producer librar is rather C-traditional +with various types as return values (quite different +from the consumer library interfaces). The style +generally follows the style of the original DWARF1 reader +proposed as an interface to DWARF. +When the style of the reader interfaces was changed (1994) in the +dwarf reader ( See the "Document History" +section of "A Consumer Library Interface to DWARF") +the interfaces here were not changed as it seemed like +too much of a change for the two applications then using +the interface! So this interface remains in the traditional C style +of returning various data types with various (somewhat inconsistent) +means of indicating failure. + +.H 2 "Document History" +This document originally prominently referenced +"UNIX International Programming Languages Special Interest Group " +(PLSIG). +Both UNIX International and the +affiliated Programming Languages Special Interest Group +are defunct +(UNIX is a registered trademark of UNIX System Laboratories, Inc. +in the United States and other countries). +Nothing except the general interface style is actually +related to anything shown to the PLSIG +(this document was open sourced with libdwarf in the mid 1990's). +.P +See "http://www.dwarfstd.org" for information on current +DWARF standards and committee activities. + +.H 2 "Definitions" +DWARF debugging information entries (DIEs) are the segments of information +placed in the \f(CW.debug_info\fP and related +sections by compilers, assemblers, and linkage +editors that, in conjunction with line number entries, are necessary for +symbolic source-level debugging. +Refer to the document +"\fIDWARF Debugging Information Format\fP" from UI PLSIG for a more complete +description of these entries. + +.P +This document adopts all the terms and definitions in +"\fIDWARF Debugging Information Format\fP" version 2. +and the "\fIA Consumer Library Interface to DWARF\fP". + +.P +In addition, this document refers to Elf, the ATT/USL System V +Release 4 object format. +This is because the library was first developed for that object +format. +Hopefully the functions defined here can easily be +applied to other object formats. + +.H 2 "Overview" +The remaining sections of this document describe a proposed producer +(compiler or assembler) interface to \fILibdwarf\fP, first by describing +the purpose of additional types defined by the interface, followed by +descriptions of the available operations. +This document assumes you +are thoroughly familiar with the information contained in the +\fIDWARF +Debugging Information Format\fP document, and +"\fIA Consumer Library Interface to DWARF\fP". + +.P +The interface necessarily knows a little bit about the object format +(which is assumed to be Elf). We make an attempt to make this knowledge +as limited as possible. For example, \fILibdwarf\fP does not do the +writing of object data to the disk. The producer program does that. + +.H 2 "Revision History" +.VL 15 +.LI "March 1993" +Work on dwarf2 sgi producer draft begins +.LI "March 1999" +Adding a function to allow any number of trips +thru the dwarf_get_section_bytes() call. +.LI "April 10 1999" +Added support for assembler text output of dwarf +(as when the output must pass thru an assembler). +Revamped internals for better performance and +simpler provision for differences in ABI. +.LI "Sep 1, 1999" +Added support for little- and cross- endian +debug info creation. +.LI "May 7 2007" +This library interface now cleans up, deallocating +all memory it uses (the application simply calls +dwarf_producer_finish(dbg)). +.LE + +.H 1 "Type Definitions" + +.H 2 "General Description" +The \fIlibdwarf.h\fP +header file contains typedefs and preprocessor +definitions of types and symbolic names +used to reference objects of \fI Libdwarf \fP . +The types defined by typedefs contained in \fI libdwarf.h\fP +all use the convention of adding \fI Dwarf_ \fP +as a prefix to +indicate that they refer to objects used by Libdwarf. +The prefix \fI Dwarf_P_\fP is used for objects +referenced by the \fI Libdwarf\fP +Producer when there are similar but distinct +objects used by the Consumer. + +.H 2 "Namespace issues" +Application programs should avoid creating names +beginning with +\f(CWDwarf_\fP +\f(CWdwarf_\fP +or +\f(CWDW_\fP +as these are reserved to dwarf and libdwarf. + +.H 1 "libdwarf and Elf and relocations" +Much of the description below presumes that Elf is the object +format in use. +The library is probably usable with other object formats +that allow arbitrary sections to be created. + +.H 2 "binary or assembler output" +With +\f(CWDW_DLC_STREAM_RELOCATIONS\fP +(see below) +it is assumed that the calling app will simply +write the streams and relocations directly into +an Elf file, without going thru an assembler. + +With +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP +the calling app must either +A) generate binary relocation streams and write +the generated debug information streams and +the relocation streams direct to an elf file +or +B) generate assembler output text for an assembler +to read and produce an object file. + +With case B) the libdwarf-calling application must +use the relocation information to change +points of each binary stream into references to +symbolic names. +It is necessary for the assembler to be +willing to accept and generate relocations +for references from arbitrary byte boundaries. +For example: +.sp +.nf +.in +4 + .data 0a0bcc #producing 3 bytes of data. + .word mylabel #producing a reference + .word endlabel - startlable #producing absolute length +.in -4 +.fi +.sp + + + + +.H 2 "libdwarf relationship to Elf" +When the documentation below refers to 'an elf section number' +it is really only dependent on getting (via the callback +function passed by the caller of +\f(CWdwarf_producer_init()\fP) +a sequence of integers back (with 1 as the lowest). + +When the documentation below refers to 'an Elf symbol index' +it is really dependent on +Elf symbol numbers +only if +\f(CWDW_DLC_STREAM_RELOCATIONS\fP +are being generated (see below). +With +\f(CWDW_DLC_STREAM_RELOCATIONS\fP +the library is generating Elf relocations +and the section numbers in binary form so +the section numbers and symbol indices must really +be Elf (or elf-like) numbers. + + +With +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP +the values passed as symbol indexes can be any +integer set or even pointer set. +All that libdwarf assumes is that where values +are unique they get unique values. +Libdwarf does not generate any kind of symbol table +from the numbers and does not check their +uniqueness or lack thereof. + +.H 2 "libdwarf and relocations" +With +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP +libdwarf creates binary streams of debug information +and arrays of relocation information describing +the necessary relocation. +The Elf section numbers and symbol numbers appear +nowhere in the binary streams. Such appear +only in the relocation information and the passed-back +information from calls requesting the relocation information. +As a consequence, the 'symbol indices' can be +any pointer or integer value as the caller must +arrange that the output deal with relocations. + +With +\f(CWDW_DLC_STREAM_RELOCATIONS\fP +all the relocations are directly created by libdwarf +as binary streams (libdwarf only creates the streams +in memory, +it does not write them to disk). + +.H 2 "symbols, addresses, and offsets" +The following applies to calls that +pass in symbol indices, addresses, and offsets, such +as +\f(CWdwarf_add_AT_targ_address() \fP +\f(CWdwarf_add_arange_b()\fP +and +\f(CWdwarf_add_frame_fde_b()\fP. + +With +\f(CWDW_DLC_STREAM_RELOCATIONS\fP +a passed in address is one of: +a) a section offset and the (non-global) symbol index of +a section symbol. +b) A symbol index (global symbol) and a zero offset. + +With \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP +the same approach can be used, or, instead, +a passed in address may be +c) a symbol handle and an offset. +In this case, since it is up to the calling app to +generate binary relocations (if appropriate) +or to turn the binary stream into +a text stream (for input to an assembler, if appropriate) +the application has complete control of the interpretation +of the symbol handles. + + + +.H 1 "Memory Management" + +Several of the functions that comprise the \fILibdwarf\fP +producer interface dynamically allocate values and some +return pointers to those spaces. +The dynamically allocated spaces +can not be reclaimed (and must +not be freed) except by \f(CWdwarf_producer_finish(dbg)\fP. + +All data for a particular \f(CWDwarf_P_Debug\fP descriptor +is separate from the data for any other +\f(CWDwarf_P_Debug\fP descriptor in use in the library-calling +application. + +.H 2 "Read-only Properties" +All pointers returned by or as a result of a \fILibdwarf\fP call should +be assumed to point to read-only memory. +Except as defined by this document, the results are undefined for +\fILibdwarf\fP clients that attempt to write to a region pointed to by a +return value from a \fILibdwarf\fP call. + +.H 2 "Storage Deallocation" +Calling \f(CWdwarf_producer_finish(dbg)\fP frees all the space, and +invalidates all pointers returned from \f(CWLibdwarf\fP functions on +or descended from \f(CWdbg\fP). + +.H 1 "Functional Interface" +This section describes the functions available in the \fILibdwarf\fP +library. Each function description includes its definition, followed +by a paragraph describing the function's operation. + +.P +The functions may be categorized into groups: +\fIinitialization and termination operations\fP, +\fIdebugging information entry creation\fP, +\fIElf section callback function\fP, +\fIattribute creation\fP, +\fIexpression creation\fP, +\fIline number creation\fP, +\fIfast-access (aranges) creation\fP, +\fIfast-access (pubnames) creation\fP, +\fIfast-access (weak names) creation\fP, +\fImacro information creation\fP, +\fIlow level (.debug_frame) creation\fP, +and +\fIlocation list (.debug_loc) creation\fP. + +.P +The following sections describe these functions. + +.H 2 "Initialization and Termination Operations" +These functions setup \f(CWLibdwarf\fP to accumulate debugging information +for an object, usually a compilation-unit, provided by the producer. +The actual addition of information is done by functions in the other +sections of this document. Once all the information has been added, +functions from this section are used to transform the information to +appropriate byte streams, and help to write out the byte streams to +disk. + +Typically then, a producer application +would create a \f(CWDwarf_P_Debug\fP +descriptor to gather debugging information for a particular +compilation-unit using \f(CWdwarf_producer_init()\fP. +The producer application would +use this \f(CWDwarf_P_Debug\fP descriptor to accumulate debugging +information for this object using functions from other sections of +this document. +Once all the information had been added, it would +call \f(CWdwarf_transform_to_disk_form()\fP to convert the accumulated +information into byte streams in accordance with the \f(CWDWARF\fP +standard. +The application would then repeatedly call +\f(CWdwarf_get_section_bytes()\fP +for each of the \f(CW.debug_*\fP created. +This gives the producer +information about the data bytes to be written to disk. +At this point, +the producer would release all resource used by \f(CWLibdwarf\fP for +this object by calling \f(CWdwarf_producer_finish()\fP. + +It is also possible to create assembler-input character streams +from the byte streams created by this library. +This feature requires slightly different interfaces than +direct binary output. +The details are mentioned in the text. + +.H 3 "dwarf_producer_init()" + +.DS +\f(CWDwarf_P_Debug dwarf_producer_init( + Dwarf_Unsigned flags, + Dwarf_Callback_Func func, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, + Dwarf_Error *error) \fP +.DE +The function \f(CWdwarf_producer_init() \fP returns a new +\f(CWDwarf_P_Debug\fP descriptor that can be used to add \f(CWDwarf\fP +information to the object. +On error it returns \f(CWDW_DLV_BADADDR\fP. +\f(CWflags\fP determine whether the target object is 64-bit or 32-bit. +\f(CWfunc\fP is a pointer to a function called-back from \f(CWLibdwarf\fP +whenever \f(CWLibdwarf\fP needs to create a new object section (as it will +for each .debug_* section and related relocation section). +\f(CWerrhand\fP +is a pointer to a function that will be used for handling errors detected +by \f(CWLibdwarf\fP. \f(CWerrarg\fP is the default error argument used +by the function pointed to by \f(CWerrhand\fP. +.P +The \f(CWflags\fP +values are as follows: +.in +4 +\f(CWDW_DLC_WRITE\fP +is required. +The values +\f(CWDW_DLC_READ\fP +\f(CWDW_DLC_RDWR\fP +are not supported by the producer and must not be passed. + +If +\f(CWDW_DLC_SIZE_64\fP +is not OR'd into \f(CWflags\fP +then +\f(CWDW_DLC_SIZE_32\fP +is assumed. +Oring in both is an error. + +If +\f(CWDW_DLC_ISA_IA64\fP +is not OR'd into \f(CWflags\fP +then +\f(CWDW_DLC_ISA_MIPS\fP +is assumed. +Oring in both is an error. + +If +\f(CWDW_DLC_TARGET_BIGENDIAN\fP +is not OR'd into \f(CWflags\fP +then +endianness the same as the host is assumed. + +If +\f(CWDW_DLC_TARGET_LITTLEENDIAN\fP +is not OR'd into \f(CWflags\fP +then +endianness the same as the host is assumed. + +If both +\f(CWDW_DLC_TARGET_LITTLEENDIAN\fP +and +\f(CWDW_DLC_TARGET_BIGENDIAN\fP +are or-d in it is an error. + + + +Either one of two output forms is specifiable: +\f(CWDW_DLC_STREAM_RELOCATIONS\fP +or +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP . + +The default is +\f(CWDW_DLC_STREAM_RELOCATIONS\fP . +The +\f(CWDW_DLC_STREAM_RELOCATIONS\fP +are relocations in a binary stream (as used +in a MIPS Elf object). + +The +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP +are the same relocations but expressed in an +array of structures defined by libdwarf, +which the caller of the relevant function +(see below) must deal with appropriately. +This method of expressing relocations allows +the producer-application to easily produce +assembler text output of debugging information. + + +If +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP +is OR'd into \f(CWflags\fP +then relocations are returned not as streams +but thru an array of structures. + +.in -4 +.P +The function \f(CWfunc\fP +must be provided by the user of this library. +Its prototype is: +.DS +\f(CWtypedef int (*Dwarf_Callback_Func)( + char* name, + int size, + Dwarf_Unsigned type, + Dwarf_Unsigned flags, + Dwarf_Unsigned link, + Dwarf_Unsigned info, + int* sect_name_index, + int* error) \fP +.DE +For each section in the object file that \f(CWlibdwarf\fP +needs to create, it calls this function once, passing in +the section \f(CWname\fP, the section \f(CWtype\fP, +the section \f(CWflags\fP, the \f(CWlink\fP field, and +the \f(CWinfo\fP field. +For an Elf object file these values +should be appropriate Elf section header values. +For example, for relocation callbacks, the \f(CWlink\fP +field is supposed to be set (by the app) to the index +of the symtab section (the link field passed thru the +callback must be ignored by the app). +And, for relocation callbacks, the \f(CWinfo\fP field +is passed as the elf section number of the section +the relocations apply to. + +On success +the user function should return the Elf section number of the +newly created Elf section. +.P +On success, the function should also set the integer +pointed to by \f(CWsect_name_index\fP to the +Elf symbol number assigned in the Elf symbol table of the +new Elf section. +This symbol number is needed with relocations +dependent on the relocation of this new section. +Because "int *" is not guaranteed to work with elf 'symbols' +that are really pointers, +It is better to use the +\f(CWdwarf_producer_init_b()\fP +interface. +.P +For example, the \f(CW.debug_line\fP section's third +data element (in a compilation unit) is the offset from the +beginning of the \f(CW.debug_info\fP section of the compilation +unit entry for this \f(CW.debug_line\fP set. +The relocation entry in \f(CW.rel.debug_line\fP +for this offset +must have the relocation symbol index of the +symbol \f(CW.debug_info\fP returned +by the callback of that section-creation through +the pointer \f(CWsect_name_index\fP. +.P +On failure, the function should return -1 and set the \f(CWerror\fP +integer to an error code. +.P +Nothing in libdwarf actually depends on the section index +returned being a real Elf section. +The Elf section is simply useful for generating relocation +records. +Similarly, the Elf symbol table index returned thru +the \f(CWsect_name_index\fP must simply be an index +that can be used in relocations against this section. +The application will probably want to note the +values passed to this function in some form, even if +no Elf file is being produced. + +.H 3 "dwarf_producer_init_b()" + +.DS +\f(CWDwarf_P_Debug dwarf_producer_init_b( + Dwarf_Unsigned flags, + Dwarf_Callback_Func_b func, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, + Dwarf_Error *error) \fP +.DE +The function \f(CWdwarf_producer_init_b() \fP +is the same as \f(CWdwarf_producer_init() \fP +except that the callback function uses +Dwarf_Unsigned rather than int as the +type of the symbol-index returned to libdwarf +thru the pointer argument (see below). +.P +The \f(CWflags\fP +values are as follows: +.in +4 +\f(CWDW_DLC_WRITE\fP +is required. +The values +\f(CWDW_DLC_READ\fP +\f(CWDW_DLC_RDWR\fP +are not supported by the producer and must not be passed. + +If +\f(CWDW_DLC_SIZE_64\fP +is not OR'd into \f(CWflags\fP +then +\f(CWDW_DLC_SIZE_32\fP +is assumed. +Oring in both is an error. + +If +\f(CWDW_DLC_ISA_IA64\fP +is not OR'd into \f(CWflags\fP +then +\f(CWDW_DLC_ISA_MIPS\fP +is assumed. +Oring in both is an error. + +Either one of two output forms are specifiable: +\f(CWDW_DLC_STREAM_RELOCATIONS\fP +or +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP . +\f(CWdwarf_producer_init_b() \fP +is usable with +either output form. + +Either one of two output forms is specifiable: +\f(CWDW_DLC_STREAM_RELOCATIONS\fP +or +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP . + +The default is +\f(CWDW_DLC_STREAM_RELOCATIONS\fP . +The +\f(CWDW_DLC_STREAM_RELOCATIONS\fP +are relocations in a binary stream (as used +in a MIPS Elf object). + +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP +are OR'd into flags +to cause +the same relocations to be expressed in an +array of structures defined by libdwarf, +which the caller of the relevant function +(see below) must deal with appropriately. +This method of expressing relocations allows +the producer-application to easily produce +assembler text output of debugging information. + +.in -4 +.P +The function \f(CWfunc\fP +must be provided by the user of this library. +Its prototype is: +.DS +\f(CWtypedef int (*Dwarf_Callback_Func_b)( + char* name, + int size, + Dwarf_Unsigned type, + Dwarf_Unsigned flags, + Dwarf_Unsigned link, + Dwarf_Unsigned info, + Dwarf_Unsigned* sect_name_index, + int* error) \fP +.DE +For each section in the object file that \f(CWlibdwarf\fP +needs to create, it calls this function once, passing in +the section \f(CWname\fP, the section \f(CWtype\fP, +the section \f(CWflags\fP, the \f(CWlink\fP field, and +the \f(CWinfo\fP field. For an Elf object file these values +should be appropriate Elf section header values. +For example, for relocation callbacks, the \f(CWlink\fP +field is supposed to be set (by the app) to the index +of the symtab section (the link field passed thru the +callback must be ignored by the app). +And, for relocation callbacks, the \f(CWinfo\fP field +is passed as the elf section number of the section +the relocations apply to. + +On success +the user function should return the Elf section number of the +newly created Elf section. +.P +On success, the function should also set the integer +pointed to by \f(CWsect_name_index\fP to the +Elf symbol number assigned in the Elf symbol table of the +new Elf section. +This symbol number is needed with relocations +dependent on the relocation of this new section. +.P +For example, the \f(CW.debug_line\fP section's third +data element (in a compilation unit) is the offset from the +beginning of the \f(CW.debug_info\fP section of the compilation +unit entry for this \f(CW.debug_line\fP set. +The relocation entry in \f(CW.rel.debug_line\fP +for this offset +must have the relocation symbol index of the +symbol \f(CW.debug_info\fP returned +by the callback of that section-creation through +the pointer \f(CWsect_name_index\fP. +.P +On failure, the function should return -1 and set the \f(CWerror\fP +integer to an error code. +.P +Nothing in libdwarf actually depends on the section index +returned being a real Elf section. +The Elf section is simply useful for generating relocation +records. +Similarly, the Elf symbol table index returned thru +the \f(CWsect_name_index\fP must simply be an index +that can be used in relocations against this section. +The application will probably want to note the +values passed to this function in some form, even if +no Elf file is being produced. + +Note that the \f(CWDwarf_Callback_Func_b() \fP form +passes back the sect_name_index as a Dwarf_Unsigned. +This is guaranteed large enough to hold a pointer. +(the other functional interfaces have versions with +the 'symbol index' as a Dwarf_Unsigned too. See below). + +If \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP +is in use, then the symbol index is simply an arbitrary +value (from the point of view of libdwarf) so the +caller can put anything in it: +a normal elf symbol index, +a pointer to a struct (with arbitrary contents) +(the caller must cast to/from Dwarf_Unsigned +as appropriate), +or some other kind of pointer or value. +The values show up in the +output of \f(CWdwarf_get_relocation_info()\fP +(described below) and are not emitted anywhere else. + +.H 3 "dwarf_transform_to_disk_form()" + +.DS +\f(CWDwarf_Signed dwarf_transform_to_disk_form( + Dwarf_P_Debug dbg, + Dwarf_Error* error) \fP +.DE +The function \f(CWdwarf_transform_to_disk_form() \fP does the actual +conversion of the \f(CWDwarf\fP information provided so far, to the +form that is +normally written out as \f(CWElf\fP sections. +In other words, +once all DWARF information has been passed to \f(CWLibdwarf\fP, call +\f(CWdwarf_transform_to_disk_form() \fP to transform all the accumulated +data into byte streams. +This includes turning relocation information +into byte streams (and possibly relocation arrays). +This function does not write anything to disk. If +successful, it returns a count of the number of \f(CWElf\fP sections +ready to be retrieved (and, normally, written to disk). +In case of error, it returns +\f(CWDW_DLV_NOCOUNT\fP. + + +.H 3 "dwarf_get_section_bytes()" + +.DS +\f(CWDwarf_Ptr dwarf_get_section_bytes( + Dwarf_P_Debug dbg, + Dwarf_Signed dwarf_section, + Dwarf_Signed *elf_section_index, + Dwarf_Unsigned *length, + Dwarf_Error* error)\fP +.DE +The function \f(CWdwarf_get_section_bytes() \fP must be called repetitively, +with the index \f(CWdwarf_section\fP starting at 0 and continuing for the +number of sections +returned by \f(CWdwarf_transform_to_disk_form() \fP. +It returns \f(CWNULL\fP to indicate that there are no more sections of +\f(CWDwarf\fP information. +For each non-NULL return, the return value +points to \f(CW*length\fP bytes of data that are normally +added to the output +object in \f(CWElf\fP section \f(CW*elf_section\fP by the producer application. +It is illegal to call these in any order other than 0 thru N-1 where +N is the number of dwarf sections +returned by \f(CWdwarf_transform_to_disk_form() \fP. +The \f(CWdwarf_section\fP +number is actually ignored: the data is returned as if the +caller passed in the correct dwarf_section numbers in the +required sequence. +The \f(CWerror\fP argument is not used. +.P +There is no requirement that the section bytes actually +be written to an elf file. +For example, consider the .debug_info section and its +relocation section (the call back function would resulted in +assigning 'section' numbers and the link field to tie these +together (.rel.debug_info would have a link to .debug_info). +One could examine the relocations, split the .debug_info +data at relocation boundaries, emit byte streams (in hex) +as assembler output, and at each relocation point, +emit an assembler directive with a symbol name for the assembler. +Examining the relocations is awkward though. +It is much better to use \f(CWdwarf_get_section_relocation_info() \fP +.P + +The memory space of the section byte stream is freed +by the \f(CWdwarf_producer_finish() \fP call +(or would be if the \f(CWdwarf_producer_finish() \fP +was actually correct), along +with all the other space in use with that Dwarf_P_Debug. + +.H 3 "dwarf_get_relocation_info_count()" +.DS +\f(CWint dwarf_get_relocation_info_count( + Dwarf_P_Debug dbg, + Dwarf_Unsigned *count_of_relocation_sections , + int *drd_buffer_version, + Dwarf_Error* error)\fP +.DE +The function \f(CWdwarf_get_relocation_info() \fP +returns, thru the pointer \f(CWcount_of_relocation_sections\fP, the +number of times that \f(CWdwarf_get_relocation_info() \fP +should be called. + +The function \f(CWdwarf_get_relocation_info() \fP +returns DW_DLV_OK if the call was successful (the +\f(CWcount_of_relocation_sections\fP is therefore meaningful, +though \f(CWcount_of_relocation_sections\fP +could be zero). + +\f(CW*drd_buffer_version\fP +is the value 2. +If the structure pointed to by +the \f(CW*reldata_buffer\fP +changes this number will change. +The application should verify that the number is +the version it understands (that it matches +the value of DWARF_DRD_BUFFER_VERSION (from libdwarf.h)). +The value 1 version was never used in production +MIPS libdwarf (version 1 did exist in source). + +It returns DW_DLV_NO_ENTRY if +\f(CWcount_of_relocation_sections\fP is not meaningful +because \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP was not +passed in the +\f(CWdwarf_producer_init() \fP +(or +\f(CWdwarf_producer_init_b() \fP ) call. + +It returns DW_DLV_ERROR if there was an error, +in which case +\f(CWcount_of_relocation_sections\fP is not meaningful. + +.H 3 "dwarf_get_relocation_info()" +.DS +\f(CWint dwarf_get_relocation_info( + Dwarf_P_Debug dbg, + Dwarf_Signed *elf_section_index, + Dwarf_Signed *elf_section_index_link, + Dwarf_Unsigned *relocation_buffer_count, + Dwarf_Relocation_Data *reldata_buffer, + Dwarf_Error* error)\fP +.DE + +The function \f(CWdwarf_get_relocation_info() \fP +should normally be called repetitively, +for the number of relocation sections that +\f(CWdwarf_get_relocation_info_count() \fP +indicated exist. + +It returns \f(CWDW_DLV_OK\fP to indicate that +valid values are returned thru the pointer arguments. +The \f(CWerror\fP argument is not set. + +It returns DW_DLV_NO_ENTRY if there are no entries +(the count of relocation arrays is zero.). +The \f(CWerror\fP argument is not set. + +It returns \f(CWDW_DLV_ERROR\fP if there is an error. +Calling \f(CWdwarf_get_relocation_info() \fP +more than the number of times indicated by +\f(CWdwarf_get_relocation_info_count() \fP +(without an intervening call to +\f(CWdwarf_reset_section_bytes() \fP ) +results in a return of \f(CWDW_DLV_ERROR\fP once past +the valid count. +The \f(CWerror\fP argument is set to indicate the error. + +Now consider the returned-thru-pointer values for +\f(CWDW_DLV_OK\fP . + +\f(CW*elf_section_index\fP +is the 'elf section index' of the section implied by +this group of relocations. + + +\f(CW*elf_section_index_link\fP +is the section index of the section that these +relocations apply to. + +\f(CW*relocation_buffer_count\fP +is the number of array entries of relocation information +in the array pointed to by +\f(CW*reldata_buffer\fP . + + +\f(CW*reldata_buffer\fP +points to an array of 'struct Dwarf_Relocation_Data_s' +structures. + +The version 2 array information is as follows: + +.nf +enum Dwarf_Rel_Type {dwarf_drt_none, + dwarf_drt_data_reloc, + dwarf_drt_segment_rel, + dwarf_drt_first_of_length_pair, + dwarf_drt_second_of_length_pair +}; +typedef struct Dwarf_Relocation_Data_s * Dwarf_Relocation_Data; +struct Dwarf_Relocation_Data_s { + unsigned char drd_type; /* contains Dwarf_Rel_Type */ + unsigned char drd_length; /* typically 4 or 8 */ + Dwarf_Unsigned drd_offset; /* where the data to reloc is */ + Dwarf_Unsigned drd_symbol_index; +}; + +.fi + +The \f(CWDwarf_Rel_Type\fP enum is encoded (via casts if necessary) +into the single unsigned char \f(CWdrd_type\fP field to control +the space used for this information (keep the space to 1 byte). + +The unsigned char \f(CWdrd_length\fP field +holds the size in bytes of the field to be relocated. +So for elf32 object formats with 32 bit apps, \f(CWdrd_length\fP +will be 4. For objects with MIPS -64 contents, +\f(CWdrd_length\fP will be 8. +For some dwarf 64 bit environments, such as ia64, \f(CWdrd_length\fP +is 4 for some relocations (file offsets, for example) +and 8 for others (run time +addresses, for example). + +If \f(CWdrd_type\fP is \f(CWdwarf_drt_none\fP, this is an unused slot +and it should be ignored. + +If \f(CWdrd_type\fP is \f(CWdwarf_drt_data_reloc\fP +this is an ordinary relocation. +The relocation type means either +(R_MIPS_64) or (R_MIPS_32) (or the like for +the particular ABI. +f(CWdrd_length\fP gives the length of the field to be relocated. +\f(CWdrd_offset\fP is an offset (of the +value to be relocated) in +the section this relocation stuff is linked to. +\f(CWdrd_symbol_index\fP is the symbol index (if elf symbol +indices were provided) or the handle to arbitrary +information (if that is what the caller passed in +to the relocation-creating dwarf calls) of the symbol +that the relocation is relative to. + + +When \f(CWdrd_type\fP is \f(CWdwarf_drt_first_of_length_pair\fP +the next data record will be \f(CWdrt_second_of_length_pair\fP +and the \f(CWdrd_offset\fP of the two data records will match. +The relevant 'offset' in the section this reloc applies to +should contain a symbolic pair like +.nf +.in +4 + .word second_symbol - first_symbol +.in -4 +.fi +to generate a length. +\f(CWdrd_length\fP gives the length of the field to be relocated. + +\f(CWdrt_segment_rel\fP means (R_MIPS_SCN_DISP) +is the real relocation (R_MIPS_SCN_DISP applies to +exception tables and this part may need further work). +\f(CWdrd_length\fP gives the length of the field to be relocated. + +.P +The memory space of the section byte stream is freed +by the \f(CWdwarf_producer_finish() \fP call +(or would be if the \f(CWdwarf_producer_finish() \fP +was actually correct), along +with all the other space in use with that Dwarf_P_Debug. + +.H 3 "dwarf_reset_section_bytes()" + +.DS +\f(CWvoid dwarf_reset_section_bytes( + Dwarf_P_Debug dbg + ) \fP +.DE +The function \f(CWdwarf_reset_section_bytes() \fP +is used to reset the internal information so that +\f(CWdwarf_get_section_bytes() \fP will begin (on the next +call) at the initial dwarf section again. +It also resets so that calls to +\f(CWdwarf_get_relocation_info() \fP +will begin again at the initial array of relocation information. + +Some dwarf producers need to be able to run thru +the \f(CWdwarf_get_section_bytes()\fP +and/or +the \f(CWdwarf_get_relocation_info()\fP +calls more than once and this call makes additional +passes possible. +The set of Dwarf_Ptr values returned is identical to the +set returned by the first pass. +It is acceptable to call this before finishing a pass +of \f(CWdwarf_get_section_bytes()\fP +or +\f(CWdwarf_get_relocation_info()\fP +calls. +No errors are possible as this just resets some +internal pointers. +It is unwise to call this before +\f(CWdwarf_transform_to_disk_form() \fP has been called. +.P + +.H 3 "dwarf_producer_finish()" +.DS +\f(CWDwarf_Unsigned dwarf_producer_finish( + Dwarf_P_Debug dbg, + Dwarf_Error* error) \fP +.DE +The function \f(CWdwarf_producer_finish() \fP should be called after all +the bytes of data have been copied somewhere +(normally the bytes are written to disk). +It frees all dynamic space +allocated for \f(CWdbg\fP, include space for the structure pointed to by +\f(CWdbg\fP. +This should not be called till the data have been +copied or written +to disk or are no longer of interest. +It returns non-zero if successful, and \f(CWDW_DLV_NOCOUNT\fP +if there is an error. + +.H 2 "Debugging Information Entry Creation" +The functions in this section add new \f(CWDIE\fPs to the object, +and also the relationships among the \f(CWDIE\fP to be specified +by linking them up as parents, children, left or right siblings +of each other. +In addition, there is a function that marks the +root of the graph thus created. + +.H 3 "dwarf_add_die_to_debug()" +.DS +\f(CWDwarf_Unsigned dwarf_add_die_to_debug( + Dwarf_P_Debug dbg, + Dwarf_P_Die first_die, + Dwarf_Error *error) \fP +.DE +The function \f(CWdwarf_add_die_to_debug() \fP indicates to \f(CWLibdwarf\fP +the root \f(CWDIE\fP of the \f(CWDIE\fP graph that has been built so +far. +It is intended to mark the compilation-unit \f(CWDIE\fP for the +object represented by \f(CWdbg\fP. +The root \f(CWDIE\fP is specified +by \f(CWfirst_die\fP. + +It returns \f(CW0\fP on success, and \f(CWDW_DLV_NOCOUNT\fP on error. + +.H 3 "dwarf_new_die()" +.DS +\f(CWDwarf_P_Die dwarf_new_die( + Dwarf_P_Debug dbg, + Dwarf_Tag new_tag, + Dwarf_P_Die parent, + Dwarf_P_Die child, + Dwarf_P_Die left_sibling, + Dwarf_P_Die right_sibling, + Dwarf_Error *error) \fP +.DE +The function \f(CWdwarf_new_die() \fP creates a new \f(CWDIE\fP with +its parent, child, left sibling, and right sibling \f(CWDIE\fPs +specified by \f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP, +and \f(CWright_sibling\fP, respectively. +There is no requirement +that all of these \f(CWDIE\fPs be specified, i.e. any of these +descriptors may be \f(CWNULL\fP. +If none is specified, this will +be an isolated \f(CWDIE\fP. +A \f(CWDIE\fP is +transformed to disk form by \f(CWdwarf_transform_to_disk_form() \fP +only if there is a path from +the \f(CWDIE\fP specified by \f(CWdwarf_add_die_to_debug\fP to it. +This function returns \f(CWDW_DLV_BADADDR\fP on error. + +\f(CWnew_tag\fP is the tag which is given to the new \f(CWDIE\fP. +\f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP, and +\f(CWright_sibling\fP are pointers to establish links to existing +\f(CWDIE\fPs. Only one of \f(CWparent\fP, \f(CWchild\fP, +\f(CWleft_sibling\fP, and \f(CWright_sibling\fP may be non-NULL. +If \f(CWparent\fP (\f(CWchild\fP) is given, the \f(CWDIE\fP is +linked into the list after (before) the \f(CWDIE\fP pointed to. +If \f(CWleft_sibling\fP (\f(CWright_sibling\fP) is given, the +\f(CWDIE\fP is linked into the list after (before) the \f(CWDIE\fP +pointed to. + +To add attributes to the new \f(CWDIE\fP, use the \f(CWAttribute Creation\fP +functions defined in the next section. + +.H 3 "dwarf_die_link()" +.DS +\f(CWDwarf_P_Die dwarf_die_link( + Dwarf_P_Die die, + Dwarf_P_Die parent, + Dwarf_P_Die child, + Dwarf_P_Die left-sibling, + Dwarf_P_Die right_sibling, + Dwarf_Error *error) \fP +.DE +The function \f(CWdwarf_die_link() \fP links an existing \f(CWDIE\fP +described by the given \f(CWdie\fP to other existing \f(CWDIE\fPs. +The given \f(CWdie\fP can be linked to a parent \f(CWDIE\fP, a child +\f(CWDIE\fP, a left sibling \f(CWDIE\fP, or a right sibling \f(CWDIE\fP +by specifying non-NULL \f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP, +and \f(CWright_sibling\fP \f(CWDwarf_P_Die\fP descriptors. +It returns +the given \f(CWDwarf_P_Die\fP descriptor, \f(CWdie\fP, on success, +and \f(CWDW_DLV_BADADDR\fP on error. + +Only one of \f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP, +and \f(CWright_sibling\fP may be non-NULL. +If \f(CWparent\fP +(\f(CWchild\fP) is given, the \f(CWDIE\fP is linked into the list +after (before) the \f(CWDIE\fP pointed to. +If \f(CWleft_sibling\fP +(\f(CWright_sibling\fP) is given, the \f(CWDIE\fP is linked into +the list after (before) the \f(CWDIE\fP pointed to. +Non-NULL links +overwrite the corresponding links the given \f(CWdie\fP may have +had before the call to \f(CWdwarf_die_link() \fP. + +.H 2 "Attribute Creation" +The functions in this section add attributes to a \f(CWDIE\fP. +These functions return a \f(CWDwarf_P_Attribute\fP descriptor +that represents the attribute added to the given \f(CWDIE\fP. +In most cases the return value is only useful to determine if +an error occurred. + +Some of the attributes have values that are relocatable. +They +need a symbol with respect to which the linker will perform +relocation. +This symbol is specified by means of an index into +the Elf symbol table for the object +(of course, the symbol index can be more general than an index). + +.H 3 "dwarf_add_AT_location_expr()" +.DS +\f(CWDwarf_P_Attribute dwarf_add_AT_location_expr( + Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_P_Expr loc_expr, + Dwarf_Error *error) \fP +.DE +The function \f(CWdwarf_add_AT_location_expr() \fP adds the attribute +specified by \f(CWattr\fP to the \f(CWDIE\fP descriptor given by +\f(CWownerdie\fP. The attribute should be one that has a location +expression as its value. The location expression that is the value +is represented by the \f(CWDwarf_P_Expr\fP descriptor \f(CWloc_expr\fP. +It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute +given, on success. On error it returns \f(CWDW_DLV_BADADDR\fP. + +.H 3 "dwarf_add_AT_name()" +.DS +\f(CWDwarf_P_Attribute dwarf_add_AT_name( + Dwarf_P_Die ownerdie, + char *name, + Dwarf_Error *error) \fP +.DE +The function \f(CWdwarf_add_AT_name() \fP adds the string specified +by \f(CWname\fP as the value of the \f(CWDW_AT_name\fP attribute +for the given \f(CWDIE\fP, \f(CWownerdie\fP. It returns the +\f(CWDwarf_P_attribute\fP descriptor for the \f(CWDW_AT_name\fP +attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. + +.H 3 "dwarf_add_AT_comp_dir()" +.DS +\f(CWDwarf_P_Attribute dwarf_add_AT_comp_dir( + Dwarf_P_Die ownerdie, + char *current_working_directory, + Dwarf_Error *error) \fP +.DE +The function \f(CWdwarf_add_AT_comp_dir() \fP adds the string given by +\f(CWcurrent_working_directory\fP as the value of the \f(CWDW_AT_comp_dir\fP +attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. +It returns the \f(CWDwarf_P_Attribute\fP for this attribute on success. +On error, it returns \f(CWDW_DLV_BADADDR\fP. + +.H 3 "dwarf_add_AT_producer()" +.DS +\f(CWDwarf_P_Attribute dwarf_add_AT_producer( + Dwarf_P_Die ownerdie, + char *producer_string, + Dwarf_Error *error) \fP +.DE +The function \f(CWdwarf_add_AT_producer() \fP adds the string given by +\f(CWproducer_string\fP as the value of the \f(CWDW_AT_producer\fP +attribute for the \f(CWDIE\fP given by \f(CWownerdie\fP. It returns +the \f(CWDwarf_P_Attribute\fP descriptor representing this attribute +on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. + +.H 3 "dwarf_add_AT_const_value_signedint()" +.DS +\f(CWDwarf_P_Attribute dwarf_add_AT_const_value_signedint( + Dwarf_P_Die ownerdie, + Dwarf_Signed signed_value, + Dwarf_Error *error) \fP +.DE +The function \f(CWdwarf_add_AT_const_value_signedint() \fP adds the +given \f(CWDwarf_Signed\fP value \f(CWsigned_value\fP as the value +of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP +described by the given \f(CWownerdie\fP. It returns the +\f(CWDwarf_P_Attribute\fP descriptor for this attribute on success. +On error, it returns \f(CWDW_DLV_BADADDR\fP. + +.H 3 "dwarf_add_AT_const_value_unsignedint()" +.DS +\f(CWDwarf_P_Attribute dwarf_add_AT_const_value_unsignedint( + Dwarf_P_Die ownerdie, + Dwarf_Unsigned unsigned_value, + Dwarf_Error *error) \fP +.DE +The function \f(CWdwarf_add_AT_const_value_unsignedint() \fP adds the +given \f(CWDwarf_Unsigned\fP value \f(CWunsigned_value\fP as the value +of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described +by the given \f(CWownerdie\fP. It returns the \f(CWDwarf_P_Attribute\fP +descriptor for this attribute on success. On error, it returns +\f(CWDW_DLV_BADADDR\fP. + +.H 3 "dwarf_add_AT_const_value_string()" +.DS +\f(CWDwarf_P_Attribute dwarf_add_AT_const_value_string( + Dwarf_P_Die ownerdie, + char *string_value, + Dwarf_Error *error) \fP +.DE +The function \f(CWdwarf_add_AT_const_value_string() \fP adds the +string value given by \f(CWstring_value\fP as the value of the +\f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described +by the given \f(CWownerdie\fP. It returns the \f(CWDwarf_P_Attribute\fP +descriptor for this attribute on success. On error, it returns +\f(CWDW_DLV_BADADDR\fP. + +.H 3 "dwarf_add_AT_targ_address()" +.DS +\f(CWDwarf_P_Attribute dwarf_add_AT_targ_address( + Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Unsigned pc_value, + Dwarf_Signed sym_index, + Dwarf_Error *error) \fP +.DE +The function \f(CWdwarf_add_AT_targ_address() \fP adds an attribute that +belongs to the "address" class to the die specified by \f(CWownerdie\fP. +The attribute is specified by \f(CWattr\fP, and the object that the +\f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The relocatable +address that is the value of the attribute is specified by \f(CWpc_value\fP. +The symbol to be used for relocation is specified by the \f(CWsym_index\fP, +which is the index of the symbol in the Elf symbol table. + +It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute +on success, and \f(CWDW_DLV_BADADDR\fP on error. + + +.H 3 "dwarf_add_AT_targ_address_b()" +.DS +\f(CWDwarf_P_Attribute dwarf_add_AT_targ_address_b( + Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Unsigned pc_value, + Dwarf_Unsigned sym_index, + Dwarf_Error *error) \fP +.DE +The function \f(CWdwarf_add_AT_targ_address_b() \fP +is identical to \f(CWdwarf_add_AT_targ_address_b() \fP +except that \f(CWsym_index() \fP is guaranteed to +be large enough that it can contain a pointer to +arbitrary data (so the caller can pass in a real elf +symbol index, an arbitrary number, or a pointer +to arbitrary data). +The ability to pass in a pointer thru \f(CWsym_index() \fP +is only usable with +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. + +The \f(CWpc_value\fP +is put into the section stream output and +the \f(CWsym_index\fP is applied to the relocation +information. + +Do not use this function for attr \f(CWDW_AT_high_pc\fP +if the value to be recorded is an offset (not a pc) +[ use \f(CWdwarf_add_AT_unsigned_const()\fP (for example) +instead]. + +.H 3 "dwarf_add_AT_dataref()" +.DS +\f(CWDwarf_P_Attribute dwarf_add_AT_dataref( + Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Unsigned pc_value, + Dwarf_Unsigned sym_index, + Dwarf_Error *error) \fP +.DE +This is very similar to \f(CWdwarf_add_AT_targ_address_b() \fP +but results in a different FORM (results in DW_FORM_data4 +or DW_FORM_data8). + +Useful for adding relocatable addresses in location lists. + +\f(CWsym_index() \fP is guaranteed to +be large enough that it can contain a pointer to +arbitrary data (so the caller can pass in a real elf +symbol index, an arbitrary number, or a pointer +to arbitrary data). +The ability to pass in a pointer thru \f(CWsym_index() \fP +is only usable with +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. + +The \f(CWpc_value\fP +is put into the section stream output and +the \f(CWsym_index\fP is applied to the relocation +information. + +Do not use this function for \f(CWDW_AT_high_pc\fP, use +\f(CWdwarf_add_AT_unsigned_const()\fP [ (for example) +if the value to be recorded is +an offset of \f(CWDW_AT_low_pc\fP] +or \f(CWdwarf_add_AT_targ_address_b()\fP [ if the value +to be recorded is an address]. + +.H 3 "dwarf_add_AT_ref_address()" +.DS +\f(CWDwarf_P_Attribute dwarf_add_AT_ref_address( + Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Unsigned pc_value, + Dwarf_Unsigned sym_index, + Dwarf_Error *error) \fP +.DE + +This is very similar to \f(CWdwarf_add_AT_targ_address_b() \fP +but results in a different FORM (results in \f(CWDW_FORM_ref_addr\fP +being generated). + +Useful for \f(CWDW_AT_type\fP and \f(CWDW_AT_import\fP attributes. + +\f(CWsym_index() \fP is guaranteed to +be large enough that it can contain a pointer to +arbitrary data (so the caller can pass in a real elf +symbol index, an arbitrary number, or a pointer +to arbitrary data). +The ability to pass in a pointer thru \f(CWsym_index() \fP +is only usable with +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. + +The \f(CWpc_value\fP +is put into the section stream output and +the \f(CWsym_index\fP is applied to the relocation +information. + +Do not use this function for \f(CWDW_AT_high_pc\fP. + + +.H 3 "dwarf_add_AT_unsigned_const()" +.DS +\f(CWDwarf_P_Attribute dwarf_add_AT_unsigned_const( + Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Unsigned value, + Dwarf_Error *error) \fP +.DE +The function \f(CWdwarf_add_AT_unsigned_const() \fP adds an attribute +with a \f(CWDwarf_Unsigned\fP value belonging to the "constant" class, +to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that +the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute +is specified by \f(CWattr\fP, and its value is specified by \f(CWvalue\fP. + +It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute +on success, and \f(CWDW_DLV_BADADDR\fP on error. + +.H 3 "dwarf_add_AT_signed_const()" +.DS +\f(CWDwarf_P_Attribute dwarf_add_AT_signed_const( + Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Signed value, + Dwarf_Error *error) \fP +.DE +The function \f(CWdwarf_add_AT_signed_const() \fP adds an attribute +with a \f(CWDwarf_Signed\fP value belonging to the "constant" class, +to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that +the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute +is specified by \f(CWattr\fP, and its value is specified by \f(CWvalue\fP. + +It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute +on success, and \f(CWDW_DLV_BADADDR\fP on error. + +.H 3 "dwarf_add_AT_reference()" +.DS +\f(CWDwarf_P_Attribute dwarf_add_AT_reference( + Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_P_Die otherdie, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_AT_reference()\fP adds an attribute +with a value that is a reference to another \f(CWDIE\fP in the +same compilation-unit to the \f(CWDIE\fP specified by \f(CWownerdie\fP. +The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. +The attribute is specified by \f(CWattr\fP, and the other \f(CWDIE\fP +being referred to is specified by \f(CWotherdie\fP. + +This cannot generate DW_FORM_ref_addr references to +\f(CWDIE\fPs in other compilation units. + +It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute +on success, and \f(CWDW_DLV_BADADDR\fP on error. + +.H 3 "dwarf_add_AT_flag()" +.DS +\f(CWDwarf_P_Attribute dwarf_add_AT_flag( + Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Small flag, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_AT_flag()\fP adds an attribute with +a \f(CWDwarf_Small\fP value belonging to the "flag" class, to the +\f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the +\f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute +is specified by \f(CWattr\fP, and its value is specified by \f(CWflag\fP. + +It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute +on success, and \f(CWDW_DLV_BADADDR\fP on error. + +.H 3 "dwarf_add_AT_string()" +.DS +\f(CWDwarf_P_Attribute dwarf_add_AT_string( + Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + char *string, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_AT_string()\fP adds an attribute with a +value that is a character string to the \f(CWDIE\fP specified by +\f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is +specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, +and its value is pointed to by \f(CWstring\fP. + +It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute +on success, and \f(CWDW_DLV_BADADDR\fP on error. + +.H 2 "Expression Creation" +The following functions are used to convert location expressions into +blocks so that attributes with values that are location expressions +can store their values as a \f(CWDW_FORM_blockn\fP value. This is for +both .debug_info and .debug_loc expression blocks. + +To create an expression, first call \f(CWdwarf_new_expr()\fP to get +a \f(CWDwarf_P_Expr\fP descriptor that can be used to build up the +block containing the location expression. Then insert the parts of +the expression in prefix order (exactly the order they would be +interpreted in in an expression interpreter). The bytes of the +expression are then built-up as specified by the user. + +.H 3 "dwarf_new_expr()" +.DS +\f(CWDwarf_Expr dwarf_new_expr( + Dwarf_P_Debug dbg, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_new_expr()\fP creates a new expression area +in which a location expression stream can be created. It returns +a \f(CWDwarf_P_Expr\fP descriptor that can be used to add operators +to build up a location expression. It returns \f(CWNULL\fP on error. + +.H 3 "dwarf_add_expr_gen()" +.DS +\f(CWDwarf_Unsigned dwarf_add_expr_gen( + Dwarf_P_Expr expr, + Dwarf_Small opcode, + Dwarf_Unsigned val1, + Dwarf_Unsigned val2, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_expr_gen()\fP takes an operator specified +by \f(CWopcode\fP, along with up to 2 operands specified by \f(CWval1\fP, +and \f(CWval2\fP, converts it into the \f(CWDwarf\fP representation and +appends the bytes to the byte stream being assembled for the location +expression represented by \f(CWexpr\fP. The first operand, if present, +to \f(CWopcode\fP is in \f(CWval1\fP, and the second operand, if present, +is in \f(CWval2\fP. Both the operands may actually be signed or unsigned +depending on \f(CWopcode\fP. It returns the number of bytes in the byte +stream for \f(CWexpr\fP currently generated, i.e. after the addition of +\f(CWopcode\fP. It returns \f(CWDW_DLV_NOCOUNT\fP on error. + +The function \f(CWdwarf_add_expr_gen()\fP works for all opcodes except +those that have a target address as an operand. This is because it does +not set up a relocation record that is needed when target addresses are +involved. + +.H 3 "dwarf_add_expr_addr()" +.DS +\f(CWDwarf_Unsigned dwarf_add_expr_addr( + Dwarf_P_Expr expr, + Dwarf_Unsigned address, + Dwarf_Signed sym_index, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_expr_addr()\fP is used to add the +\f(CWDW_OP_addr\fP opcode to the location expression represented +by the given \f(CWDwarf_P_Expr\fP descriptor, \f(CWexpr\fP. The +value of the relocatable address is given by \f(CWaddress\fP. +The symbol to be used for relocation is given by \f(CWsym_index\fP, +which is the index of the symbol in the Elf symbol table. It returns +the number of bytes in the byte stream for \f(CWexpr\fP currently +generated, i.e. after the addition of the \f(CWDW_OP_addr\fP operator. +It returns \f(CWDW_DLV_NOCOUNT\fP on error. + +.H 3 "dwarf_add_expr_addr_b()" +.DS +\f(CWDwarf_Unsigned dwarf_add_expr_addr_b( + Dwarf_P_Expr expr, + Dwarf_Unsigned address, + Dwarf_Unsigned sym_index, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_expr_addr_f()\fP is +identical to \f(CWdwarf_add_expr_addr()\fP +except that \f(CWsym_index() \fP is guaranteed to +be large enough that it can contain a pointer to +arbitrary data (so the caller can pass in a real elf +symbol index, an arbitrary number, or a pointer +to arbitrary data). +The ability to pass in a pointer thru \f(CWsym_index() \fP +is only usable with +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. + + + +.H 3 "dwarf_expr_current_offset()" +.DS +\f(CWDwarf_Unsigned dwarf_expr_current_offset( + Dwarf_P_Expr expr, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_expr_current_offset()\fP returns the number +of bytes currently in the byte stream for the location expression +represented by the given \fCW(Dwarf_P_Expr\fP descriptor, \f(CWexpr\fP. +It returns \f(CWDW_DLV_NOCOUNT\fP on error. + +.H 3 "dwarf_expr_into_block()" +.DS +\f(CWDwarf_Addr dwarf_expr_into_block( + Dwarf_P_Expr expr, + Dwarf_Unsigned *length, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_expr_into_block()\fP returns the address +of the start of the byte stream generated for the location expression +represented by the given \f(CWDwarf_P_Expr\fP descriptor, \f(CWexpr\fP. +The length of the byte stream is returned in the location pointed to +by \f(CWlength\fP. It returns \f(CWDW_DLV_BADADDR\fP on error. + +.H 2 "Line Number Operations" +These are operations on the .debug_line section. +They provide +information about instructions in the program and the source +lines the instruction come from. +Typically, code is generated +in contiguous blocks, which may then be relocated as contiguous +blocks. +To make the provision of relocation information more +efficient, the information is recorded in such a manner that only +the address of the start of the block needs to be relocated. +This is done by providing the address of the first instruction +in a block using the function \f(CWdwarf_lne_set_address()\fP. +Information about the instructions in the block are then added +using the function \f(CWdwarf_add_line_entry()\fP, which specifies +offsets from the address of the first instruction. +The end of +a contiguous block is indicated by calling the function +\f(CWdwarf_lne_end_sequence()\fP. +.P +Line number operations do not support +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. + +.H 3 "dwarf_add_line_entry()" +.DS +\f(CWDwarf_Unsigned dwarf_add_line_entry( + Dwarf_P_Debug dbg, + Dwarf_Unsigned file_index, + Dwarf_Addr code_offset, + Dwarf_Unsigned lineno, + Dwarf_Signed column_number, + Dwarf_Bool is_source_stmt_begin, + Dwarf_Bool is_basic_block_begin, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_line_entry()\fP adds an entry to the +section containing information about source lines. +It specifies +in \f(CWcode_offset\fP, the offset from the address set using +\f(CWdwarfdwarf_lne_set_address()\fP, of the address of the first +instruction in a contiguous block. +The source file that gave rise +to the instruction is specified by \f(CWfile_index\fP, the source +line number is specified by \f(CWlineno\fP, and the source column +number is specified by \f(CWcolumn_number\fP +(column numbers begin at 1) +(if the source column is unknown, specify 0). +\f(CWfile_index\fP +is the index of the source file in a list of source files which is +built up using the function \f(CWdwarf_add_file_decl()\fP. + +\f(CWis_source_stmt_begin\fP is a boolean flag that is true only if +the instruction at \f(CWcode_address\fP is the first instruction in +the sequence generated for the source line at \f(CWlineno\fP. Similarly, +\f(CWis_basic_block_begin\fP is a boolean flag that is true only if +the instruction at \f(CWcode_address\fP is the first instruction of +a basic block. + +It returns \f(CW0\fP on success, and \f(CWDW_DLV_NOCOUNT\fP on error. + +.H 3 "dwarf_lne_set_address()" +.DS +\f(CWDwarf_Unsigned dwarf_lne_set_address( + Dwarf_P_Debug dbg, + Dwarf_Addr offs, + Dwarf_Unsigned symidx, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_lne_set_address()\fP sets the target address +at which a contiguous block of instructions begin. Information about +the instructions in the block is added to .debug_line using calls to +\f(CWdwarfdwarf_add_line_entry()\fP which specifies the offset of each +instruction in the block relative to the start of the block. This is +done so that a single relocation record can be used to obtain the final +target address of every instruction in the block. + +The relocatable address of the start of the block of instructions is +specified by \f(CWoffs\fP. The symbol used to relocate the address +is given by \f(CWsymidx\fP, which is normally the index of the symbol in the +Elf symbol table. + +It returns \f(CW0\fP on success, and \f(CWDW_DLV_NOCOUNT\fP on error. + +.H 3 "dwarf_lne_end_sequence()" +.DS +\f(CWDwarf_Unsigned dwarf_lne_end_sequence( + Dwarf_P_Debug dbg, + Dwarf_Addr address; + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_lne_end_sequence()\fP indicates the end of a +contiguous block of instructions. +\f(CWaddress()\fP +should be just higher than the end of the last address in the +sequence of instructions. +block of instructions, a call to \f(CWdwarf_lne_set_address()\fP will +have to be made to set the address of the start of the target address +of the block, followed by calls to \f(CWdwarf_add_line_entry()\fP for +each of the instructions in the block. + +It returns \f(CW0\fP on success, and \f(CWDW_DLV_NOCOUNT\fP on error. + +.H 3 "dwarf_add_directory_decl()" +.DS +\f(CWDwarf_Unsigned dwarf_add_directory_decl( + Dwarf_P_Debug dbg, + char *name, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_directory_decl()\fP adds the string +specified by \f(CWname\fP to the list of include directories in +the statement program prologue of the .debug_line section. +The +string should therefore name a directory from which source files +have been used to create the present object. + +It returns the index of the string just added, in the list of include +directories for the object. +This index is then used to refer to this +string. +It returns \f(CWDW_DLV_NOCOUNT\fP on error. + +.H 3 "dwarf_add_file_decl()" +.DS +\f(CWDwarf_Unsigned dwarf_add_file_decl( + Dwarf_P_Debug dbg, + char *name, + Dwarf_Unsigned dir_idx, + Dwarf_Unsigned time_mod, + Dwarf_Unsigned length, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_file_decl()\fP adds the name of a source +file that contributed to the present object. +The name of the file is +specified by \f(CWname\fP (which must not be the empty string +or a null pointer, it must point to +a string with length greater than 0). +In case the name is not a fully-qualified +pathname, it is prefixed with the name of the directory specified by +\f(CWdir_idx\fP. +\f(CWdir_idx\fP is the index of the directory to be +prefixed in the list builtup using \f(CWdwarf_add_directory_decl()\fP. + +\f(CWtime_mod\fP gives the time at which the file was last modified, +and \f(CWlength\fP gives the length of the file in bytes. + +It returns the index of the source file in the list built up so far +using this function, on success. This index can then be used to +refer to this source file in calls to \f(CWdwarf_add_line_entry()\fP. +On error, it returns \f(CWDW_DLV_NOCOUNT\fP. + +.H 2 "Fast Access (aranges) Operations" +These functions operate on the .debug_aranges section. + +.H 3 "dwarf_add_arange()" +.DS +\f(CWDwarf_Unsigned dwarf_add_arange( + Dwarf_P_Debug dbg, + Dwarf_Addr begin_address, + Dwarf_Unsigned length, + Dwarf_Signed symbol_index, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_arange()\fP adds another address range +to be added to the section +containing address range information, .debug_aranges. +The relocatable start address of the range is +specified by \f(CWbegin_address\fP, and the length of the address +range is specified by \f(CWlength\fP. +The relocatable symbol to be +used to relocate the start of the address range is specified by +\f(CWsymbol_index\fP, which is normally +the index of the symbol in the Elf +symbol table. + +It returns a non-zero value on success, and \f(CW0\fP on error. + +.H 3 "dwarf_add_arange_b()" +.DS +\f(CWDwarf_Unsigned dwarf_add_arange_b( + Dwarf_P_Debug dbg, + Dwarf_Addr begin_address, + Dwarf_Unsigned length, + Dwarf_Unsigned symbol_index, + Dwarf_Unsigned end_symbol_index, + Dwarf_Addr offset_from_end_symbol, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_arange_b()\fP adds another address range +to be added to the section containing +address range information, .debug_aranges. + +If +\f(CWend_symbol_index is not zero\fP +we are using two symbols to create a length +(must be \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP to be useful) +.sp +.in +2 +\f(CWbegin_address\fP +is the offset from the symbol specified by +\f(CWsymbol_index\fP . +\f(CWoffset_from_end_symbol\fP +is the offset from the symbol specified by +\f(CWend_symbol_index\fP. +\f(CWlength\fP is ignored. +This begin-end pair will be show up in the +relocation array returned by +\f(CWdwarf_get_relocation_info() \fP +as a +\f(CWdwarf_drt_first_of_length_pair\fP +and +\f(CWdwarf_drt_second_of_length_pair\fP +pair of relocation records. +The consuming application will turn that pair into +something conceptually identical to +.sp +.nf +.in +4 + .word end_symbol + offset_from_end - \\ + ( start_symbol + begin_address) +.in -4 +.fi +.sp +The reason offsets are allowed on the begin and end symbols +is to allow the caller to re-use existing labels +when the labels are available +and the corresponding offset is known +(economizing on the number of labels in use). +The 'offset_from_end - begin_address' +will actually be in the binary stream, not the relocation +record, so the app processing the relocation array +must read that stream value into (for example) +net_offset and actually emit something like +.sp +.nf +.in +4 + .word end_symbol - start_symbol + net_offset +.in -4 +.fi +.sp +.in -2 + +If +\f(CWend_symbol_index\fP is zero +we must be given a length +(either +\f(CWDW_DLC_STREAM_RELOCATIONS\fP +or +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP +): +.sp +.in +2 +The relocatable start address of the range is +specified by \f(CWbegin_address\fP, and the length of the address +range is specified by \f(CWlength\fP. +The relocatable symbol to be +used to relocate the start of the address range is specified by +\f(CWsymbol_index\fP, which is normally +the index of the symbol in the Elf +symbol table. +The +\f(CWoffset_from_end_symbol\fP +is ignored. +.in -2 + + +It returns a non-zero value on success, and \f(CW0\fP on error. + + +.H 2 "Fast Access (pubnames) Operations" +These functions operate on the .debug_pubnames section. +.sp +.H 3 "dwarf_add_pubname()" +.DS +\f(CWDwarf_Unsigned dwarf_add_pubname( + Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *pubname_name, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_pubname()\fP adds the pubname specified +by \f(CWpubname_name\fP to the section containing pubnames, i.e. + .debug_pubnames. The \f(CWDIE\fP that represents the function +being named is specified by \f(CWdie\fP. + +It returns a non-zero value on success, and \f(CW0\fP on error. + +.H 2 "Fast Access (weak names) Operations" +These functions operate on the .debug_weaknames section. + +.H 3 "dwarf_add_weakname()" +.DS +\f(CWDwarf_Unsigned dwarf_add_weakname( + Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *weak_name, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_weakname()\fP adds the weak name specified +by \f(CWweak_name\fP to the section containing weak names, i.e. + .debug_weaknames. The \f(CWDIE\fP that represents the function +being named is specified by \f(CWdie\fP. + +It returns a non-zero value on success, and \f(CW0\fP on error. + +.H 2 "Static Function Names Operations" +The .debug_funcnames section contains the names of static function +names defined in the object, and also the offsets of the \f(CWDIE\fPs +that represent the definitions of the functions in the .debug_info +section. + +.H 3 "dwarf_add_funcname()" +.DS +\f(CWDwarf_Unsigned dwarf_add_funcname( + Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *func_name, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_funcname()\fP adds the name of a static +function specified by \f(CWfunc_name\fP to the section containing the +names of static functions defined in the object represented by \f(CWdbg\fP. +The \f(CWDIE\fP that represents the definition of the function is +specified by \f(CWdie\fP. + +It returns a non-zero value on success, and \f(CW0\fP on error. + +.H 2 "File-scope User-defined Type Names Operations" +The .debug_typenames section contains the names of file-scope +user-defined types in the given object, and also the offsets +of the \f(CWDIE\fPs that represent the definitions of the types +in the .debug_info section. + +.H 3 "dwarf_add_typename()" +.DS +\f(CWDwarf_Unsigned dwarf_add_typename( + Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *type_name, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_typename()\fP adds the name of a file-scope +user-defined type specified by \f(CWtype_name\fP to the section that +contains the names of file-scope user-defined type. The object that +this section belongs to is specified by \f(CWdbg\fP. The \f(CWDIE\fP +that represents the definition of the type is specified by \f(CWdie\fP. + +It returns a non-zero value on success, and \f(CW0\fP on error. + +.H 2 "File-scope Static Variable Names Operations" +The .debug_varnames section contains the names of file-scope static +variables in the given object, and also the offsets of the \f(CWDIE\fPs +that represent the definition of the variables in the .debug_info +section. + +.H 3 "dwarf_add_varname()" +.DS +\f(CWDwarf_Unsigned dwarf_add_varname( + Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *var_name, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_varname()\fP adds the name of a file-scope +static variable specified by \f(CWvar_name\fP to the section that +contains the names of file-scope static variables defined by the +object represented by \f(CWdbg\fP. The \f(CWDIE\fP that represents +the definition of the static variable is specified by \f(CWdie\fP. + +It returns a non-zero value on success, and \f(CW0\fP on error. + +.H 2 "Macro Information Creation" +All strings passed in by the caller are copied by these +functions, so the space in which the caller provides the strings +may be ephemeral (on the stack, or immediately reused or whatever) +without this causing any difficulty. + +.H 3 "dwarf_def_macro()" +.DS +\f(CWint dwarf_def_macro(Dwarf_P_Debug dbg, + Dwarf_Unsigned lineno, + char *name + char *value, + Dwarf_Error *error);\fP +.DE +Adds a macro definition. +The \f(CWname\fP argument should include the parentheses +and parameter names if this is a function-like macro. +Neither string should contain extraneous whitespace. +\f(CWdwarf_def_macro()\fP adds the mandated space after the +name and before the value in the +output DWARF section(but does not change the +strings pointed to by the arguments). +If this is a definition before any files are read, +\f(CWlineno\fP should be 0. +Returns \f(CWDW_DLV_ERROR\fP +and sets \f(CWerror\fP +if there is an error. +Returns \f(CWDW_DLV_OK\fP if the call was successful. + + +.H 3 "dwarf_undef_macro()" +.DS +\f(CWint dwarf_undef_macro(Dwarf_P_Debug dbg, + Dwarf_Unsigned lineno, + char *name, + Dwarf_Error *error);\fP +.DE +Adds a macro un-definition note. +If this is a definition before any files are read, +\f(CWlineno\fP should be 0. +Returns \f(CWDW_DLV_ERROR\fP +and sets \f(CWerror\fP +if there is an error. +Returns \f(CWDW_DLV_OK\fP if the call was successful. + + +.H 3 "dwarf_start_macro_file()" +.DS +\f(CWint dwarf_start_macro_file(Dwarf_P_Debug dbg, + Dwarf_Unsigned lineno, + Dwarf_Unsigned fileindex, + Dwarf_Error *error);\fP +.DE +\f(CWfileindex\fP is an index in the .debug_line header: +the index of +the file name. +See the function \f(CWdwarf_add_file_decl()\fP. +The \f(CWlineno\fP should be 0 if this file is +the file of the compilation unit source itself +(which, of course, is not a #include in any +file). +Returns \f(CWDW_DLV_ERROR\fP +and sets \f(CWerror\fP +if there is an error. +Returns \f(CWDW_DLV_OK\fP if the call was successful. + + +.H 3 "dwarf_end_macro_file()" +.DS +\f(CWint dwarf_end_macro_file(Dwarf_P_Debug dbg, + Dwarf_Error *error);\fP +.DE +Returns \f(CWDW_DLV_ERROR\fP +and sets \f(CWerror\fP +if there is an error. +Returns \f(CWDW_DLV_OK\fP if the call was successful. + +.H 3 "dwarf_vendor_ext()" +.DS +\f(CWint dwarf_vendor_ext(Dwarf_P_Debug dbg, + Dwarf_Unsigned constant, + char * string, + Dwarf_Error* error); \fP +.DE +The meaning of the \f(CWconstant\fP and the\f(CWstring\fP +in the macro info section +are undefined by DWARF itself, but the string must be +an ordinary null terminated string. +This call is not an extension to DWARF. +It simply enables storing +macro information as specified in the DWARF document. +Returns \f(CWDW_DLV_ERROR\fP +and sets \f(CWerror\fP +if there is an error. +Returns \f(CWDW_DLV_OK\fP if the call was successful. + + +.H 2 "Low Level (.debug_frame) operations" +These functions operate on the .debug_frame section. Refer to +\f(CWlibdwarf.h\fP for the register names and register assignment +mapping. Both of these are necessarily machine dependent. + +.H 3 "dwarf_new_fde()" +.DS +\f(CWDwarf_P_Fde dwarf_new_fde( + Dwarf_P_Debug dbg, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_new_fde()\fP returns a new \f(CWDwarf_P_Fde\fP +descriptor that should be used to build a complete \f(CWFDE\fP. +Subsequent calls to routines that build up the \f(CWFDE\fP should use +the same \f(CWDwarf_P_Fde\fP descriptor. + +It returns a valid \f(CWDwarf_P_Fde\fP descriptor on success, and +\f(CWDW_DLV_BADADDR\fP on error. + +.H 3 "dwarf_add_frame_cie()" +.DS +\f(CWDwarf_Unsigned dwarf_add_frame_cie( + Dwarf_P_Debug dbg, + char *augmenter, + Dwarf_Small code_align, + Dwarf_Small data_align, + Dwarf_Small ret_addr_reg, + Dwarf_Ptr init_bytes, + Dwarf_Unsigned init_bytes_len, + Dwarf_Error *error);\fP +.DE +The function +\f(CWdwarf_add_frame_cie()\fP +creates a \f(CWCIE\fP, +and returns an index to it, that should be used to refer to this +\f(CWCIE\fP. +\f(CWCIE\fPs are used by \f(CWFDE\fPs to setup +initial values for frames. +The augmentation string for the \f(CWCIE\fP +is specified by \f(CWaugmenter\fP. +The code alignment factor, +data alignment factor, and the return address register for the +\f(CWCIE\fP are specified by \f(CWcode_align\fP, \f(CWdata_align\fP, +and \f(CWret_addr_reg\fP respectively. +\f(CWinit_bytes\fP points +to the bytes that represent the instructions for the \f(CWCIE\fP +being created, and \f(CWinit_bytes_len\fP specifies the number +of bytes of instructions. + +There is no convenient way to generate the \f(CWinit_bytes\fP +stream. +One just +has to calculate it by hand or separately +generate something with the +correct sequence and use dwarfdump -v and elfdump -h and some +kind of hex dumper to see the bytes. +This is a serious inconvenience! + +It returns an index to the \f(CWCIE\fP just created on success. +On error it returns \f(CWDW_DLV_NOCOUNT\fP. + +.H 3 "dwarf_add_frame_fde()" +.DS +\f(CWDwarf_Unsigned dwarf_add_frame_fde( + Dwarf_P_Debug dbg, + Dwarf_P_Fde fde, + Dwarf_P_Die die, + Dwarf_Unsigned cie, + Dwarf_Addr virt_addr, + Dwarf_Unsigned code_len, + Dwarf_Unsigned sym_idx, + Dwarf_Error* error)\fP +.DE +The function \f(CWdwarf_add_frame_fde()\fP adds the \f(CWFDE\fP +specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the +object represented by the given \f(CWdbg\fP. +\f(CWdie\fP specifies +the \f(CWDIE\fP that represents the function whose frame information +is specified by the given \f(CWfde\fP. +\f(CWcie\fP specifies the +index of the \f(CWCIE\fP that should be used to setup the initial +conditions for the given frame. + + +It returns an index to the given \f(CWfde\fP. + + +.H 3 "dwarf_add_frame_fde_b()" +.DS +\f(CWDwarf_Unsigned dwarf_add_frame_fde_b( + Dwarf_P_Debug dbg, + Dwarf_P_Fde fde, + Dwarf_P_Die die, + Dwarf_Unsigned cie, + Dwarf_Addr virt_addr, + Dwarf_Unsigned code_len, + Dwarf_Unsigned sym_idx, + Dwarf_Unsigned sym_idx_of_end, + Dwarf_Addr offset_from_end_sym, + Dwarf_Error* error)\fP +.DE +This function is like +\f(CWdwarf_add_frame_fde()\fP +except that +\f(CWdwarf_add_frame_fde_b()\fP +has new arguments to allow use +with +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. + +The function \f(CWdwarf_add_frame_fde_b()\fP +adds the +\f(CWFDE\fP +specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the +object represented by the given \f(CWdbg\fP. +\f(CWdie\fP specifies +the \f(CWDIE\fP that represents the function whose frame information +is specified by the given \f(CWfde\fP. +\f(CWcie\fP specifies the +index of the \f(CWCIE\fP that should be used to setup the initial +conditions for the given frame. +\f(CWvirt_addr\fP represents the +relocatable address at which the code for the given function begins, +and \f(CWsym_idx\fP gives the index of the relocatable symbol to +be used to relocate this address (\f(CWvirt_addr\fP that is). +\f(CWcode_len\fP specifies the size in bytes of the machine instructions +for the given function. + +If \f(CWsym_idx_of_end\fP is zero +(may be +\f(CWDW_DLC_STREAM_RELOCATIONS\fP +or +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP +): +.sp +.in +2 +\f(CWvirt_addr\fP represents the +relocatable address at which the code for the given function begins, +and \f(CWsym_idx\fP gives the index of the relocatable symbol to +be used to relocate this address (\f(CWvirt_addr\fP that is). +\f(CWcode_len\fP +specifies the size in bytes of the machine instructions +for the given function. +\f(CWsym_idx_of_end\fP +and +\f(CWoffset_from_end_sym\fP +are unused. +.in -2 +.sp + + +If \f(CWsym_idx_of_end\fP is non-zero +(must be \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP to be useful): +.sp +.in +2 +\f(CWvirt_addr\fP +is the offset from the symbol specified by +\f(CWsym_idx\fP . +\f(CWoffset_from_end_sym\fP +is the offset from the symbol specified by +\f(CWsym_idx_of_end\fP. +\f(CWcode_len\fP is ignored. +This begin-end pair will be show up in the +relocation array returned by +\f(CWdwarf_get_relocation_info() \fP +as a +\f(CWdwarf_drt_first_of_length_pair\fP +and +\f(CWdwarf_drt_second_of_length_pair\fP +pair of relocation records. +The consuming application will turn that pair into +something conceptually identical to +.sp +.nf +.in +4 + .word end_symbol + begin - \\ + ( start_symbol + offset_from_end) +.in -4 +.fi +.sp +The reason offsets are allowed on the begin and end symbols +is to allow the caller to re-use existing labels +when the labels are available +and the corresponding offset is known +(economizing on the number of labels in use). +The 'offset_from_end - begin_address' +will actually be in the binary stream, not the relocation +record, so the app processing the relocation array +must read that stream value into (for example) +net_offset and actually emit something like +.sp +.nf +.in +4 + .word end_symbol - start_symbol + net_offset +.in -4 +.fi +.sp +.in -2 + +It returns an index to the given \f(CWfde\fP. + +On error, it returns \f(CWDW_DLV_NOCOUNT\fP. + +.H 3 "dwarf_add_frame_info_b()" +.DS +\f(CWDwarf_Unsigned dwarf_add_frame_info_b( + Dwarf_P_Debug dbg, + Dwarf_P_Fde fde, + Dwarf_P_Die die, + Dwarf_Unsigned cie, + Dwarf_Addr virt_addr, + Dwarf_Unsigned code_len, + Dwarf_Unsigned sym_idx, + Dwarf_Unsigned end_symbol_index, + Dwarf_Addr offset_from_end_symbol, + Dwarf_Signed offset_into_exception_tables, + Dwarf_Unsigned exception_table_symbol, + Dwarf_Error* error)\fP +.DE +The function \f(CWdwarf_add_frame_fde()\fP adds the \f(CWFDE\fP +specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the +object represented by the given \f(CWdbg\fP. +\f(CWdie\fP specifies +the \f(CWDIE\fP that represents the function whose frame information +is specified by the given \f(CWfde\fP. +\f(CWcie\fP specifies the +index of the \f(CWCIE\fP that should be used to setup the initial +conditions for the given frame. +\f(CWoffset_into_exception_tables\fP specifies the +offset into \f(CW.MIPS.eh_region\fP elf section where the exception tables +for this function begins. +\f(CWexception_table_symbol\fP gives the index of +the relocatable symbol to be used to relocate this offset. + + +If +\f(CWend_symbol_index is not zero\fP +we are using two symbols to create a length +(must be \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP to be useful) +.sp +.in +2 +\f(CWvirt_addr\fP +is the offset from the symbol specified by +\f(CWsym_idx\fP . +\f(CWoffset_from_end_symbol\fP +is the offset from the symbol specified by +\f(CWend_symbol_index\fP. +\f(CWcode_len\fP is ignored. +This begin-end pair will be show up in the +relocation array returned by +\f(CWdwarf_get_relocation_info() \fP +as a +\f(CWdwarf_drt_first_of_length_pair\fP +and +\f(CWdwarf_drt_second_of_length_pair\fP +pair of relocation records. +The consuming application will turn that pair into +something conceptually identical to +.sp +.nf +.in +4 + .word end_symbol + offset_from_end_symbol - \\ + ( start_symbol + virt_addr) +.in -4 +.fi +.sp +The reason offsets are allowed on the begin and end symbols +is to allow the caller to re-use existing labels +when the labels are available +and the corresponding offset is known +(economizing on the number of labels in use). +The 'offset_from_end - begin_address' +will actually be in the binary stream, not the relocation +record, so the app processing the relocation array +must read that stream value into (for example) +net_offset and actually emit something like +.sp +.nf +.in +4 + .word end_symbol - start_symbol + net_offset +.in -4 +.fi +.sp +.in -2 + +If +\f(CWend_symbol_index\fP is zero +we must be given a code_len value +(either +\f(CWDW_DLC_STREAM_RELOCATIONS\fP +or +\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP +): +.sp +.in +2 +The relocatable start address of the range is +specified by \f(CWvirt_addr\fP, and the length of the address +range is specified by \f(CWcode_len\fP. +The relocatable symbol to be +used to relocate the start of the address range is specified by +\f(CWsymbol_index\fP, which is normally +the index of the symbol in the Elf +symbol table. +The +\f(CWoffset_from_end_symbol\fP +is ignored. +.in -2 + + +It returns an index to the given \f(CWfde\fP. + +On error, it returns \f(CWDW_DLV_NOCOUNT\fP. + + +.H 3 "dwarf_add_frame_info()" + +.DS +\f(CWDwarf_Unsigned dwarf_add_frame_info( + Dwarf_P_Debug dbg, + Dwarf_P_Fde fde, + Dwarf_P_Die die, + Dwarf_Unsigned cie, + Dwarf_Addr virt_addr, + Dwarf_Unsigned code_len, + Dwarf_Unsigned sym_idx, + Dwarf_Signed offset_into_exception_tables, + Dwarf_Unsigned exception_table_symbol, + Dwarf_Error* error)\fP +.DE +The function \f(CWdwarf_add_frame_fde()\fP adds the \f(CWFDE\fP +specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the +object represented by the given \f(CWdbg\fP. \f(CWdie\fP specifies +the \f(CWDIE\fP that represents the function whose frame information +is specified by the given \f(CWfde\fP. \f(CWcie\fP specifies the +index of the \f(CWCIE\fP that should be used to setup the initial +conditions for the given frame. \f(CWvirt_addr\fP represents the +relocatable address at which the code for the given function begins, +and \f(CWsym_idx\fP gives the index of the relocatable symbol to +be used to relocate this address (\f(CWvirt_addr\fP that is). +\f(CWcode_len\fP specifies the size in bytes of the machine instructions +for the given function. \f(CWoffset_into_exception_tables\fP specifies the +offset into \f(CW.MIPS.eh_region\fP elf section where the exception tables +for this function begins. \f(CWexception_table_symbol\fP gives the index of +the relocatable symbol to be used to relocate this offset. + +It returns an index to the given \f(CWfde\fP. + +.H 3 "dwarf_fde_cfa_offset()" +.DS +\f(CWDwarf_P_Fde dwarf_fde_cfa_offset( + Dwarf_P_Fde fde, + Dwarf_Unsigned reg, + Dwarf_Signed offset, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_fde_cfa_offset()\fP appends a \f(CWDW_CFA_offset\fP +operation to the \f(CWFDE\fP, specified by \f(CWfde\fP, being constructed. +The first operand of the \f(CWDW_CFA_offset\fP operation is specified by +\f(CWreg\P. The register specified should not exceed 6 bits. The second +operand of the \f(CWDW_CFA_offset\fP operation is specified by \f(CWoffset\fP. + +It returns the given \f(CWfde\fP on success. + +It returns \f(CWDW_DLV_BADADDR\fP on error. + +.H 3 "dwarf_add_fde_inst()" +.DS +\f(CWDwarf_P_Fde dwarf_add_fde_inst( + Dwarf_P_Fde fde, + Dwarf_Small op, + Dwarf_Unsigned val1, + Dwarf_Unsigned val2, + Dwarf_Error *error)\fP +.DE +The function \f(CWdwarf_add_fde_inst()\fP adds the operation specified +by \f(CWop\fP to the \f(CWFDE\fP specified by \f(CWfde\fP. Upto two +operands can be specified in \f(CWval1\fP, and \f(CWval2\fP. Based on +the operand specified \f(CWLibdwarf\fP decides how many operands are +meaningful for the operand. It also converts the operands to the +appropriate datatypes (they are passed to \f(CWdwarf_add_fde_inst\fP +as \f(CWDwarf_Unsigned\fP). + +It returns the given \f(CWfde\fP on success, and \f(CWDW_DLV_BADADDR\fP +on error. + +.S +.TC 1 1 4 +.CS diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2p.1.pdf Binary file tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2p.1.pdf has changed diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarfdefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarfdefs.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,91 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + +/* libdwarfdefs.h +*/ + +#ifndef LIBDWARFDEFS_H +#define LIBDWARFDEFS_H + +/* We want __uint32_t and __uint64_t and __int32_t __int64_t + properly defined but not duplicated, since duplicate typedefs + are not legal C. +*/ +/* + HAVE___UINT32_T + HAVE___UINT64_T will be set by configure if + our 4 types are predefined in compiler +*/ + + +#if (!defined(HAVE___UINT32_T)) && defined(HAVE___UINT32_T_IN_SGIDEFS_H) +#include /* sgidefs.h defines them */ +#define HAVE___UINT32_T 1 +#endif + +#if (!defined(HAVE___UINT64_T)) && defined(HAVE___UINT64_T_IN_SGIDEFS_H) +#include /* sgidefs.h defines them */ +#define HAVE___UINT64_T 1 +#endif + + +#if (!defined(HAVE___UINT32_T)) && \ + defined(HAVE_SYS_TYPES_H) && \ + defined(HAVE___UINT32_T_IN_SYS_TYPES_H) +# include +#define HAVE___UINT32_T 1 +#endif + +#if (!defined(HAVE___UINT64_T)) && \ + defined(HAVE_SYS_TYPES_H) && \ + defined(HAVE___UINT64_T_IN_SYS_TYPES_H) +# include +#define HAVE___UINT64_T 1 +#endif + +#ifndef HAVE___UINT32_T +typedef int __int32_t; +typedef unsigned __uint32_t; +#define HAVE___UINT32_T 1 +#endif + +#ifndef HAVE___UINT64_T +typedef long long __int64_t; +typedef unsigned long long __uint64_t; +#define HAVE___UINT64_T 1 +#endif + +#endif /* LIBDWARFDEFS_H */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/malloc_check.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/malloc_check.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,339 @@ +/* + + Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +/* malloc_check.c For checking dealloc completeness. + + This code is as simple as possible and works ok for + reasonable size allocation counts. + + It treats allocation as global, and so will not + work very well if an application opens more than one + Dwarf_Debug. + +*/ + +#include +#include /* for exit() and various malloc + prototypes */ +#include "config.h" +#include "dwarf_incl.h" +#include "malloc_check.h" +#ifdef WANT_LIBBDWARF_MALLOC_CHECK + +/* To turn off printing every entry, just change the define + to set PRINT_MALLOC_DETAILS 0. +*/ +#define PRINT_MALLOC_DETAILS 0 + +#define MC_TYPE_UNKNOWN 0 +#define MC_TYPE_ALLOC 1 +#define MC_TYPE_DEALLOC 2 + +struct mc_data_s { + struct mc_data_s *mc_prev; + unsigned long mc_address; /* Assumes this is large enough to hold + a pointer! */ + + long mc_alloc_number; /* Assigned in order by when record + created. */ + unsigned char mc_alloc_code; /* Allocation code, libdwarf. */ + unsigned char mc_type; + unsigned char mc_dealloc_noted; /* Used on an ALLOC node. */ + unsigned char mc_dealloc_noted_count; /* Used on an ALLOC + node. */ +}; + +/* + + +*/ +#define HASH_TABLE_SIZE 10501 +static struct mc_data_s *mc_data_hash[HASH_TABLE_SIZE]; +static long mc_data_list_size = 0; + +static char *alloc_type_name[MAX_DW_DLA + 1] = { + "", + "DW_DLA_STRING", + "DW_DLA_LOC", + "DW_DLA_LOCDESC", + "DW_DLA_ELLIST", + "DW_DLA_BOUNDS", + "DW_DLA_BLOCK", + "DW_DLA_DEBUG", + "DW_DLA_DIE", + "DW_DLA_LINE", + "DW_DLA_ATTR", + "DW_DLA_TYPE", + "DW_DLA_SUBSCR", + "DW_DLA_GLOBAL", + "DW_DLA_ERROR", + "DW_DLA_LIST", + "DW_DLA_LINEBUF", + "DW_DLA_ARANGE", + "DW_DLA_ABBREV", + "DW_DLA_FRAME_OP", + "DW_DLA_CIE", + "DW_DLA_FDE", + "DW_DLA_LOC_BLOCK", + "DW_DLA_FRAME_BLOCK", + "DW_DLA_FUNC", + "DW_DLA_TYPENAME", + "DW_DLA_VAR", + "DW_DLA_WEAK", + "DW_DLA_ADDR", + "DW_DLA_ABBREV_LIST", + "DW_DLA_CHAIN", + "DW_DLA_CU_CONTEXT", + "DW_DLA_FRAME", + "DW_DLA_GLOBAL_CONTEXT", + "DW_DLA_FILE_ENTRY", + "DW_DLA_LINE_CONTEXT", + "DW_DLA_LOC_CHAIN", + "DW_DLA_HASH_TABLE", + "DW_DLA_FUNC_CONTEXT", + "DW_DLA_TYPENAME_CONTEXT", + "DW_DLA_VAR_CONTEXT", + "DW_DLA_WEAK_CONTEXT", + "DW_DLA_PUBTYPES_CONTEXT" + /* Don't forget to expand this list if the list of codes + expands. */ +}; + +static unsigned +hash_address(unsigned long addr) +{ + unsigned long a = addr >> 2; + + return a % HASH_TABLE_SIZE; +} + +#if PRINT_MALLOC_DETAILS +static void +print_alloc_dealloc_detail(unsigned long addr, + int code, char *whichisit) +{ + fprintf(stderr, + "%s addr 0x%lx code %d (%s) entry %ld\n", + whichisit, addr, code, alloc_type_name[code], + mc_data_list_size); +} +#else +#define print_alloc_dealloc_detail(a,b,c) /* nothing */ +#endif + +/* Create a zeroed struct or die. */ +static void * +newone(void) +{ + struct mc_data_s *newd = malloc(sizeof(struct mc_data_s)); + + if (newd == 0) { + fprintf(stderr, "out of memory , # %ld\n", mc_data_list_size); + exit(1); + } + memset(newd, 0, sizeof(struct mc_data_s)); + return newd; +} + +/* Notify checker that get_alloc has allocated user data. */ +void +dwarf_malloc_check_alloc_data(void *addr_in, unsigned char code) +{ + struct mc_data_s *newd = newone(); + unsigned long addr = (unsigned long) addr_in; + struct mc_data_s **base = &mc_data_hash[hash_address(addr)]; + + print_alloc_dealloc_detail(addr, code, "alloc "); + newd->mc_address = addr; + newd->mc_alloc_code = code; + newd->mc_type = MC_TYPE_ALLOC; + newd->mc_alloc_number = mc_data_list_size; + newd->mc_prev = *base; + *base = newd; + newd->mc_alloc_number = mc_data_list_size; + mc_data_list_size += 1; +} + +static void +print_entry(char *msg, struct mc_data_s *data) +{ + fprintf(stderr, + "%s: 0x%08lx code %2d (%s) type %s dealloc noted %u ct %u\n", + msg, + (long) data->mc_address, + data->mc_alloc_code, + alloc_type_name[data->mc_alloc_code], + (data->mc_type == MC_TYPE_ALLOC) ? "alloc " : + (data->mc_type == MC_TYPE_DEALLOC) ? "dealloc" : "unknown", + (unsigned) data->mc_dealloc_noted, + (unsigned) data->mc_dealloc_noted_count); +} + +/* newd is a 'dealloc'. +*/ +static long +balanced_by_alloc_p(struct mc_data_s *newd, + long *addr_match_num, + struct mc_data_s **addr_match, + struct mc_data_s *base) +{ + struct mc_data_s *cur = base; + + for (; cur; cur = cur->mc_prev) { + if (cur->mc_address == newd->mc_address) { + if (cur->mc_type == MC_TYPE_ALLOC) { + if (cur->mc_alloc_code == newd->mc_alloc_code) { + *addr_match = cur; + *addr_match_num = cur->mc_alloc_number; + return cur->mc_alloc_number; + } else { + /* code mismatch */ + *addr_match = cur; + *addr_match_num = cur->mc_alloc_number; + return -1; + } + } else { + /* Unbalanced new/del */ + *addr_match = cur; + *addr_match_num = cur->mc_alloc_number; + return -1; + } + } + } + return -1; +} + +/* A dealloc is to take place. Ensure it balances an alloc. +*/ +void +dwarf_malloc_check_dealloc_data(void *addr_in, unsigned char code) +{ + struct mc_data_s *newd = newone(); + long prev; + long addr_match_num = -1; + struct mc_data_s *addr_match = 0; + unsigned long addr = (unsigned long) addr_in; + struct mc_data_s **base = &mc_data_hash[hash_address(addr)]; + + + print_alloc_dealloc_detail(addr, code, "dealloc "); + newd->mc_address = (unsigned long) addr; + newd->mc_alloc_code = code; + newd->mc_type = MC_TYPE_DEALLOC; + newd->mc_prev = *base; + prev = + balanced_by_alloc_p(newd, &addr_match_num, &addr_match, *base); + if (prev < 0) { + fprintf(stderr, + "Unbalanced dealloc at index %ld\n", mc_data_list_size); + print_entry("new", newd); + fprintf(stderr, "addr-match_num? %ld\n", addr_match_num); + if (addr_match) { + print_entry("prev entry", addr_match); + if (addr_match->mc_dealloc_noted > 1) { + fprintf(stderr, "Above is Duplicate dealloc!\n"); + } + } + abort(); + exit(3); + } + addr_match->mc_dealloc_noted = 1; + addr_match->mc_dealloc_noted_count += 1; + if (addr_match->mc_dealloc_noted_count > 1) { + fprintf(stderr, "Double dealloc entry %ld\n", addr_match_num); + print_entry("new dealloc entry", newd); + print_entry("bad alloc entry", addr_match); + } + *base = newd; + mc_data_list_size += 1; +} + +/* Final check for leaks. +*/ +void +dwarf_malloc_check_complete(char *msg) +{ + long i = 0; + long total = mc_data_list_size; + long hash_slots_used = 0; + long max_chain_length = 0; + + fprintf(stderr, "Run complete, %s. %ld entries\n", msg, total); + for (; i < HASH_TABLE_SIZE; ++i) { + struct mc_data_s *cur = mc_data_hash[i]; + long cur_chain_length = 0; + + if (cur == 0) + continue; + ++hash_slots_used; + for (; cur; cur = cur->mc_prev) { + ++cur_chain_length; + if (cur->mc_type == MC_TYPE_ALLOC) { + if (cur->mc_dealloc_noted) { + if (cur->mc_dealloc_noted > 1) { + fprintf(stderr, + " Duplicate dealloc! entry %ld\n", + cur->mc_alloc_number); + print_entry("duplicate dealloc", cur); + + } + continue; + } else { + fprintf(stderr, "malloc no dealloc, entry %ld\n", + cur->mc_alloc_number); + print_entry("dangle", cur); + } + } else { + /* mc_type is MC_TYPE_DEALLOC, already checked */ + + } + } + if (cur_chain_length > max_chain_length) { + max_chain_length = cur_chain_length; + } + } + fprintf(stderr, "mc hash table slots=%ld, " + "used=%ld, maxchain=%ld\n", + (long) HASH_TABLE_SIZE, hash_slots_used, max_chain_length); + return; +} + +#else + +static void nothing(){} + +#endif /* WANT_LIBBDWARF_MALLOC_CHECK */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/malloc_check.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/malloc_check.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,62 @@ +/* + + Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + +/* malloc_check.h */ + +/* A simple libdwarf-aware malloc checker. + define WANT_LIBBDWARF_MALLOC_CHECK and rebuild libdwarf + do make a checking-for-alloc-mistakes libdwarf. + NOT recommended for production use. + + When defined, also add malloc_check.c to the list of + files in Makefile. +*/ + +#undef WANT_LIBBDWARF_MALLOC_CHECK +/*#define WANT_LIBBDWARF_MALLOC_CHECK 1 */ + +#ifdef WANT_LIBBDWARF_MALLOC_CHECK + +void dwarf_malloc_check_alloc_data(void * addr,unsigned char code); +void dwarf_malloc_check_dealloc_data(void * addr,unsigned char code); +void dwarf_malloc_check_complete(char *wheremsg); /* called at exit of app */ + +#else /* !WANT_LIBBDWARF_MALLOC_CHECK */ + +#define dwarf_malloc_check_alloc_data(a,b) /* nothing */ +#define dwarf_malloc_check_dealloc_data(a,b) /* nothing */ +#define dwarf_malloc_check_complete(a) /* nothing */ + +#endif /* WANT_LIBBDWARF_MALLOC_CHECK */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/mips_extensions.mm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/mips_extensions.mm Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1266 @@ +\." +\." the following line may be removed if the ff ligature works on your machine +.lg 0 +\." set up heading formats +.ds HF 3 3 3 3 3 2 2 +.ds HP +2 +2 +1 +0 +0 +.nr Hs 5 +.nr Hb 5 +\." ============================================== +\." Put current date in the following at each rev +.ds vE rev 1.18, 31 March 2005 +\." ============================================== +\." ============================================== +.ds | | +.ds ~ ~ +.ds ' ' +.if t .ds Cw \&\f(CW +.if n .ds Cw \fB +.de Cf \" Place every other arg in Cw font, beginning with first +.if \\n(.$=1 \&\*(Cw\\$1\fP +.if \\n(.$=2 \&\*(Cw\\$1\fP\\$2 +.if \\n(.$=3 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP +.if \\n(.$=4 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4 +.if \\n(.$=5 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP +.if \\n(.$=6 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6 +.if \\n(.$=7 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP +.if \\n(.$=8 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8 +.if \\n(.$=9 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8\ +*(Cw +.. +.nr Cl 4 +.SA 1 +.TL +MIPS Extensions to DWARF Version 2.0 +.AF "" +.AU "Silicon Graphics Computer Systems" +.PF "'\*(vE'- \\\\nP -''" +.AS 1 +This document describes the MIPS/Silicon Graphics extensions +to the "DWARF Information Format" (version 2.0.0 dated July 27, 1993). +DWARF3 draft 8 (or draft 9) is out as of 2005, and +is mentioned below where applicable. +MIPS/IRIX compilers emit DWARF2 (with extensions). +.P +Rather than alter the base documents to describe the extensions +we provide this separate document. +.P +The extensions documented here are subject to change. +.P +It also describes known bugs resulting in incorrect dwarf usage. +.P +\*(vE + +.AE +.MT 4 + +.H 1 "INTRODUCTION" +.P +This +document describes MIPS extensions +to the DWARF debugging information format. +The extensions documented here are subject to change at +any time. +.H 1 "64 BIT DWARF" +.P +The DWARF2 spec has no provision for 64 bit offsets. +SGI-IRIX/MIPS Elf64 objects contain DWARF 2 with all offsets +(and addresses) as 64bit values. +This non-standard extension was adopted in 1992. +Nothing in the dwarf itself identifies the dwarf as 64bit. +This extension 64bit-offset dwarf cannot be mixed with 32bit-offset dwarf +in a single object or executable, and SGI-IRIX/MIPS compilers +and tools do not mix the sizes. +.P +In 2001 DWARF3 adopted a very different 64bit-offset +format which can be mixed usefully with 32bit-offset DWARF2 or DWARF3. +It is not very likely SGI-IRIX/MIPS compilers will switch to the +now-standard +DWARF3 64bit-offset scheme, but such a switch is theoretically +possible and would be a good idea. +.P +SGI-IRIX/MIPS Elf32 objects +contain DWARF2 with all offsets (and addresses) 32 bits. +.H 1 "How much symbol information is emitted" +The following standard DWARF V2 sections may be emitted: +.AL +.LI +Section .debug_abbrev +contains +abbreviations supporting the .debug_info section. +.LI +Section .debug_info +contains +Debug Information Entries (DIEs). +.LI +Section .debug_frame +contains +stack frame descriptions. +.LI +Section .debug_line +contains +line number information. +.LI +Section .debug_aranges +contains +address range descriptions. +.LI +Section .debug_pubnames +contains +names of global functions and data. +.P +The following +are MIPS extensions. +Theses were created to allow debuggers to +know names without having to look at +the .debug_info section. +.LI +Section .debug_weaknames +is a MIPS extension +containing .debug_pubnames-like entries describing weak +symbols. +.LI +Section .debug_funcnames +is a MIPS extension +containing .debug_pubnames-like entries describing file-static +functions (C static functions). +The gcc extension of nested subprograms (like Pascal) +adds non-global non-static functions. These should be treated like +static functions and gcc should add such to this section +so that IRIX libexc(3C) will work correctly. +Similarly, Ada functions which are non-global should be here too +so that libexc(3C) can work. +Putting it another way, every function (other than inline code) +belongs either in .debug_pubnames or in .debug_funcnames +or else libexc(3C) cannot find the function name. +.LI +Section .debug_varnames +is a MIPS extension +containing .debug_pubnames-like entries describing file-static +data symbols (C static variables). +.LI +Section .debug_typenames +is a MIPS extension +containing .debug_pubnames-like entries describing file-level +types. +.P +The following are not currently emitted. +.LI +Section .debug_macinfo +Macro information is not currently emitted. +.LI +Section .debug_loc +Location lists are not currently emitted. +.LI +Section .debug_str +The string section is not currently emitted. +.LE +.H 2 "Overview of information emitted" +We emit debug information in 3 flavors. +We mention C here. +The situation is essentially identical for f77, f90, and C++. +.AL +.LI +"default C" +We emit line information and DIEs for each subprogram. +But no local symbols and no type information. +Frame information is output. +The DW_AT_producer string has the optimization level: for example +"-O2". +We put so much in the DW_AT_producer that the string +is a significant user of space in .debug_info -- +this is perhaps a poor use of space. +When optimizing the IRIX CC/cc option -DEBUG:optimize_space +eliminates such wasted space. +Debuggers only currently use the lack of -g +of DW_AT_producer +as a hint as to how a 'step' command should be interpreted, and +the rest of the string is not used for anything (unless +a human looks at it for some reason), so if space-on-disk +is an issue, it is quite appropriate to use -DEBUG:optimize_space +and save disk space. +Every function definition (not inline instances though) is mentioned +in either .debug_pubnames or .debug_funcnames. +This is crucial to allow libexc(3C) stack-traceback to work and +show function names (for all languages). +.LI +"C with full symbols" +All possible info is emitted. +DW_AT_producer string has all options that might be of interest, +which includes -D's, -U's, and the -g option. +These options look like they came from the command line. +We put so much in the DW_AT_producer that the string +is a significant user of space in .debug_info. +this is perhaps a poor use of space. +Debuggers only currently use the -g +of DW_AT_producer +as a hint as to how a 'step' command should be interpreted, and +the rest of the string is not used for anything (unless +a human looks at it for some reason). +Every function definition (not inline instances though) is mentioned +in either .debug_pubnames or .debug_funcnames. +This is crucial to allow libexc(3C) stack-traceback to work and +show function names (for all languages). +.LI +"Assembler (-g, non -g are the same)" +Frame information is output. +No type information is emitted, but DIEs are prepared +for globals. +.LE +.H 2 "Detecting 'full symbols' (-g)" +The debugger depends on the existence of +the DW_AT_producer string to determine if the +compilation unit has full symbols or not. +It looks for -g or -g[123] and accepts these as +full symbols but an absent -g or a present -g0 +is taken to mean that only basic symbols are defined and there +are no local symbols and no type information. +.P +In various contexts the debugger will think the program is +stripped or 'was not compiled with -g' unless the -g +is in the DW_AT_producer string. +.H 2 "DWARF and strip(1)" +The DWARF section ".debug_frame" is marked SHF_MIPS_NOSTRIP +and is not stripped by the strip(1) program. +This is because the section is needed for doing +stack back traces (essential for C++ +and Ada exception handling). +.P +All .debug_* sections are marked with elf type +SHT_MIPS_DWARF. +Applications needing to access the various DWARF sections +must use the section name to discriminate between them. + +.H 2 "Evaluating location expressions" +When the debugger evaluates location expressions, it does so +in 2 stages. In stage one it simply looks for the trivial +location expressions and treats those as special cases. +.P +If the location expression is not trivial, it enters stage two. +In this case it uses a stack to evaluate the expression. +.P +If the application is a 32-bit application, it does the operations +on 32-bit values (address size values). Even though registers +can be 64 bits in a 32-bit program all evaluations are done in +32-bit quantities, so an attempt to calculate a 32-bit quantity +by taking the difference of 2 64-bit register values will not +work. The notion is that the stack machine is, by the dwarf +definition, working in address size units. +.P +These values are then expanded to 64-bit values (addresses or +offsets). This extension does not involve sign-extension. +.P +If the application is a 64-bit application, then the stack +values are all 64 bits and all operations are done on 64 bits. +.H 3 "The fbreg location op" +Compilers shipped with IRIX 6.0 and 6.1 +do not emit the fbreg location expression +and never emit the DW_AT_frame_base attribute that it +depends on. +However, this changes +with release 6.2 and these are now emitted routinely. + +.H 1 "Frame Information" +.H 2 "Initial Instructions" +The DWARF V2 spec +provides for "initial instructions" in each CIE (page 61, +section 6.4.1). +However, it does not say whether there are default +values for each column (register). +.P +Rather than force every CIE to have a long list +of bytes to initialize all 32 integer registers, +we define that the default values of all registers +(as returned by libdwarf in the frame interface) +are 'same value'. +This is a good choice for many non-register-windows +implementations. +.H 2 "Augmentation string in debug_frame" +The augmentation string we use in shipped compilers (up thru +irix6.2) is the empty string. +IRIX6.2 and later has an augmentation string +the empty string ("") +or "z" or "mti v1" +where the "v1" is a version number (version 1). +.P +We do not believe that "mti v1" was emitted as the +augmentation string in any shipped compiler. +.P +.H 3 "CIE processing based on augmentation string:" +If the augmentation string begins with 'z', then it is followed +immediately by a unsigned_leb_128 number giving the code alignment factor. +Next is a signed_leb_128 number giving the data alignment factor. +Next is a unsigned byte giving the number of the return address register. +Next is an unsigned_leb_128 number giving the length of the 'augmentation' +fields (the length of augmentation bytes, not +including the unsigned_leb_128 length itself). +As of release 6.2, the length of the CIE augmentation fields is 0. +What this means is that it is possible to add new +augmentations, z1, z2, etc and yet an old consumer to +understand the entire CIE as it can bypass the +augmentation it does not understand because the +length of the augmentation fields is present. +Presuming of course that all augmentation fields are +simply additional information, +not some 'changing of the meaning of +an existing field'. +Currently there is no CIE data in the augmentation for things +beginning with 'z'. +.P +If the augmentation string is "mti v1" or "" then it is followed +immediately by a unsigned_leb_128 number giving the code alignment factor. +Next is a signed_leb_128 number giving the data alignment factor. +Next is a unsigned byte giving the number of the return address register. +.P +If the augmentation string is something else, then the +code alignment factor is assumed to be 4 and the data alignment +factor is assumed to be -1 and the return +address register is assumed to be 31. Arbitrarily. +The library (libdwarf) assumes it does not understand the rest of the CIE. +.P +.H 3 "FDE processing based on augmentation" +If the CIE augmentation string +for an fde begins with 'z' +then the next FDE field after the address_range field +is an +unsigned_leb_128 number giving the length of the 'augmentation' +fields, and those fields follow immediately. + +.H 4 "FDE augmentation fields" +.P +If the CIE augmentation string is "mti v1" or "" +then the FDE is exactly as described in the Dwarf Document section 6.4.1. +.P +Else, if the CIE augmentation string begins with "z" +then the next field after the FDE augmentation length field +is a Dwarf_Sword size offset into +exception tables. +If the CIE augmentation string does not begin with "z" +(and is neither "mti v1" nor "") +the FDE augmentation fields are skipped (not understood). +Note that libdwarf actually (as of MIPSpro7.3 and earlier) +only tests that the initial character of the augmentation +string is 'z', and ignores the rest of the string, if any. +So in reality the test is for a _prefix_ of 'z'. +.P +If the CIE augmentation string neither starts with 'z' nor is "" +nor is "mti v1" then libdwarf (incorrectly) assumes that the +table defining instructions start next. +Processing (in libdwarf) will be incorrect. +.H 2 "Stack Pointer recovery from debug_frame" +There is no identifiable means in +DWARF2 to say that the stack register is +recovered by any particular operation. +A 'register rule' works if the caller's +stack pointer was copied to another +register. +An 'offset(N)' rule works if the caller's +stack pointer was stored on the stack. +However if the stack pointer is +some register value plus/minus some offset, +there is no means to say this in an FDE. +For MIPS/IRIX, the recovered stack pointer +of the next frame up the stack (towards main()) +is simply the CFA value of the current +frame, and the CFA value is +precisely a register (value of a register) +or a register plus offset (value of a register +plus offset). This is a software convention. +.H 1 "egcs dwarf extensions (egcs-1.1.2 extensions)" +This and following egcs sections describe +the extensions currently shown in egcs dwarf2. +Note that egcs has chosen to adopt tag and +attribute naming as if their choices were +standard dwarf, not as if they were extensions. +However, they are properly numbered as extensions. + +.H 2 "DW_TAG_format_label 0x4101" +For FORTRAN 77, Fortran 90. +Details of use not defined in egcs source, so +unclear if used. +.H 2 "DW_TAG_function_template 0x4102" +For C++. +Details of use not defined in egcs source, so +unclear if used. +.H 2 "DW_TAG_class_template 0x4103" +For C++. +Details of use not defined in egcs source, so +unclear if used. +.H 2 "DW_AT_sf_names 0x2101" +Apparently only output in DWARF1, not DWARF2. +.H 2 "DW_AT_src_info 0x2102" +Apparently only output in DWARF1, not DWARF2. +.H 2 "DW_AT_mac_info 0x2103" +Apparently only output in DWARF1, not DWARF2. +.H 2 "DW_AT_src_coords 0x2104" +Apparently only output in DWARF1, not DWARF2. +.H 2 "DW_AT_body_begin 0x2105" +Apparently only output in DWARF1, not DWARF2. +.H 2 "DW_AT_body_end 0x2106" +Apparently only output in DWARF1, not DWARF2. + +.H 1 "egcs .eh_frame (non-sgi) (egcs-1.1.2 extensions)" +egcs-1.1.2 (and earlier egcs) +emits by default a section named .eh_frame +for ia32 (and possibly other platforms) which +is nearly identical to .debug_frame in format and content. +This section is used for helping handle C++ exceptions. +.P +Because after linking there are sometimes zero-ed out bytes +at the end of the eh_frame section, the reader code in +dwarf_frame.c considers a zero cie/fde length as an indication +that it is the end of the section. +.P +.H 2 "CIE_id 0" +The section is an ALLOCATED section in an executable, and +is therefore mapped into memory at run time. +The CIE_pointer (aka CIE_id, section 6.4.1 +of the DWARF2 document) is the field that +distinguishes a CIE from an FDE. +The designers of the egcs .eh_frame section +decided to make the CIE_id +be 0 as the CIE_pointer definition is +.in +2 +the number of bytes from the CIE-pointer in the FDE back to the +applicable CIE. +.in -2 +In a dwarf .debug_frame section, the CIE_pointer is the +offset in .debug_frame of the CIE for this fde, and +since an offset can be zero of some CIE, the CIE_id +cannot be 0, but must be all 1 bits . +Note that the dwarf2.0 spec does specify the value of CIE_id +as 0xffffffff +(see section 7.23 of v2.0.0), +though earlier versions of this extensions document +incorrectly said it was not specified in the dwarf +document. +.H 2 "augmentation eh" +The augmentation string in each CIE is "eh" +which, with its following NUL character, aligns +the following word to a 32bit boundary. +Following the augmentation string is a 32bit +word with the address of the __EXCEPTION_TABLE__, +part of the exception handling data for egcs. +.H 2 "DW_CFA_GNU_window_save 0x2d" +This is effectively a flag for architectures with +register windows, and tells the unwinder code that +it must look to a previous frame for the +correct register window set. +As of this writing, egcs gcc/frame.c +indicates this is for SPARC register windows. +.H 2 "DW_CFA_GNU_args_size 0x2e" +DW_CFA_GNU_args_size has a single uleb128 argument +which is the size, in bytes, of the function's stack +at that point in the function. +.H 2 "__EXCEPTION_TABLE__" +A series of 3 32bit word entries by default: +0 word: low pc address +1 word: high pc address +2 word: pointer to exception handler code +The end of the table is +signaled by 2 words of -1 (not 3 words!). +.H 1 "Interpretations of the DWARF V2 spec" +.H 2 "template TAG spellings" +The DWARF V2 spec spells two attributes in two ways. +DW_TAG_template_type_param +(listed in Figure 1, page 7) +is spelled DW_TAG_template_type_parameter +in the body of the document (section 3.3.7, page 28). +We have adopted the spelling +DW_TAG_template_type_param. +.P +DW_TAG_template_value_param +(listed in Figure 1, page 7) +is spelled DW_TAG_template_value_parameter +in the body of the document (section 3.3.7, page 28). +We have adopted the spelling +DW_TAG_template_value_parameter. +.P +We recognize that the choices adopted are neither consistently +the longer nor the shorter name. +This inconsistency was an accident. +.H 2 DW_FORM_ref_addr confusing +Section 7.5.4, Attribute Encodings, describes +DW_FORM_ref_addr. +The description says the reference is the size of an address +on the target architecture. +This is surely a mistake, because on a 16bit-pointer-architecture +it would mean that the reference could not exceed +16 bits, which makes only +a limited amount of sense as the reference is from one +part of the dwarf to another, and could (in theory) +be *on the disk* and not limited to what fits in memory. +Since MIPS is 32 bit pointers (at the smallest) +the restriction is not a problem for MIPS/SGI. +The 32bit pointer ABIs are limited to 32 bit section sizes +anyway (as a result of implementation details). +And the 64bit pointer ABIs currently have the same limit +as a result of how the compilers and tools are built +(this has not proven to be a limit in practice, so far). +.P +This has been clarified in the DWARF3 spec and the IRIX use +of DW_FORM_ref_addr being an offset is correct. +.H 2 "Section .debug_macinfo in a debugger" +It seems quite difficult, in general, to +tie specific text(code) addresses to points in the +stream of macro information for a particular compilation unit. +So it's been difficult to see how to design a consumer +interface to libdwarf for macro information. +.P +The best (simple to implement, easy for a debugger user to +understand) candidate seems to be that +the debugger asks for macros of a given name in a compilation +unit, and the debugger responds with *all* the macros of that name. +.H 3 "only a single choice exists" +If there is exactly one, that is usable in expressions, if the +debugger is able to evaluate such. +.H 3 "multiple macros with same name". +If there are multiple macros with the same name +in a compilation unit, +the debugger (and the debugger user and the application +programmer) have +a problem: confusion is quite possible. +If the macros are simple the +debugger user can simply substitute by hand in an expression. +If the macros are complicated hand substitution will be +impractical, and the debugger will have to identify the +choices and let the debugger user choose an interpretation. +.H 2 "Section 6.1.2 Lookup by address problem" +Each entry is a beginning-address followed by a length. +And the distinguished entry 0,0 is used to denote +the end of a range of entries. +.P +This means that one must be careful not to emit a zero length, +as in a .o (object file) the beginning address of +a normal entry might be 0 (it is a section offset after all), +and the resulting 0,0 would be taken as end-of-range, not +as a valid entry. +A dwarf dumper would have trouble with such data +in an object file. +.P +In an a.out or shared object (dynamic shared object, DSO) +no text will be at address zero so in such this problem does +not arise. +.H 2 "Section 5.10 Subrange Type Entries problem" +It is specified that DW_AT_upper_bound (and lower bound) +must be signed entries if there is no object type +info to specify the bound type (Sec 5.10, end of section). +One cannot tell (with some +dwarf constant types) what the signedness is from the +form itself (like DW_FORM_data1), so it is necessary +to determine the object and type according to the rules +in 5.10 and then if all that fails, the type is signed. +It's a bit complicated and earlier versions of mips_extensions +incorrectly said signedness was not defined. +.H 2 "Section 5.5.6 Class Template Instantiations problem" +Lots of room for implementor to canonicalize +template declarations. Ie various folks won't agree. +This is not serious since a given compiler +will be consistent with itself and debuggers +will have to cope! +.H 2 "Section 2.4.3.4 # 11. operator spelling" +DW_OP_add should be DW_OP_plus (page 14) +(this mistake just one place on the page). +.H 2 "No clear specification of C++ static funcs" +There is no clear way to tell if a C++ member function +is a static member or a non-static member function. +(dwarf2read.c in gdb 4.18, for example, has this observation) +.H 2 "Misspelling of DW_AT_const_value" +Twice in appendix 1, DW_AT_const_value is misspelled +as DW_AT_constant_value. +.H 2 "Mistake in Atribute Encodings" +Section 7.5.4, "Attribute Encodings" +has a brief discussion of "constant" +which says there are 6 forms of constants. +It is incorrect in that it fails to mention (or count) +the block forms, which are clearly allowed by +section 4.1 "Data Object Entries" (see entry number 9 in +the numbered list, on constants). +.H 2 "DW_OP_bregx" +The description of DW_OP_bregx in 2.4.3.2 (Register Based +Addressing) is slightly misleading, in that it +lists the offset first. +As section 7.7.1 (Location Expression) +makes clear, in the encoding the register number +comes first. +.H 1 "MIPS attributes" +.H 2 "DW_AT_MIPS_fde" +This extension to Dwarf appears only on subprogram TAGs and has as +its value the offset, in the .debug_frame section, of the fde which +describes the frame of this function. It is an optimization of +sorts to have this present. + +.H 2 "DW_CFA_MIPS_advance_loc8 0x1d" +This obvious extension to dwarf line tables enables encoding of 8 byte +advance_loc values (for cases when such must be relocatable, +and thus must be full length). Applicable only to 64-bit objects. + +.H 2 "DW_TAG_MIPS_loop 0x4081" +For future use. Not currently emitted. +Places to be emitted and attributes that this might own +not finalized. + +.H 2 "DW_AT_MIPS_loop_begin 0x2002" +For future use. Not currently emitted. +Attribute form and content not finalized. + +.H 2 "DW_AT_MIPS_tail_loop_begin 0x2003" +For future use. Not currently emitted. +Attribute form and content not finalized. + +.H 2 "DW_AT_MIPS_epilog_begin 0x2004" +For future use. Not currently emitted. +Attribute form and content not finalized. + +.H 2 "DW_AT_MIPS_loop_unroll_factor 0x2005" +For future use. Not currently emitted. +Attribute form and content not finalized. + +.H 2 "DW_AT_MIPS_software_pipeline_depth 0x2006" +For future use. Not currently emitted. +Attribute form and content not finalized. +.H 2 "DW_AT_MIPS_linkage_name 0x2007" +The rules for mangling C++ names are not part of the +C++ standard and are different for different versions +of C++. With this extension, the compiler emits +both the DW_AT_name for things with mangled names +(recall that DW_AT_name is NOT the mangled form) +and also emits DW_AT_MIPS_linkage_name whose value +is the mangled name. +.P +This makes looking for the mangled name in other linker +information straightforward. +It also is passed (by the debugger) to the +libmangle routines to generate names to present to the +debugger user. +.H 2 "DW_AT_MIPS_stride 0x2008" +F90 allows assumed shape arguments and pointers to describe +non-contiguous memory. A (runtime) descriptor contains address, +bounds and stride information - rank and element size is known +during compilation. The extent in each dimension is given by the +bounds in a DW_TAG_subrange_type, but the stride cannot be +represented in conventional dwarf. DW_AT_MIPS_stride was added as +an attribute of a DW_TAG_subrange_type to describe the +location of the stride. +Used in the MIPSpro 7.2 (7.2.1 etc) compilers. +.P +If the stride is constant (ie: can be inferred from the type in the +usual manner) DW_AT_MIPS_stride is absent. +.P +If DW_AT_MIPS_stride is present, the attribute contains a reference +to a DIE which describes the location holding the stride, and the +DW_AT_stride_size field of DW_TAG_array_type is ignored if +present. The value of the stride is the number of +4 byte words between +elements along that axis. +.P +This applies to +.nf +a) Intrinsic types whose size is greater + or equal to 4bytes ie: real*4,integer*8 + complex etc, but not character types. + +b) Derived types (ie: structs) of any size, + unless all components are of type character. +.fi + +.H 2 "DW_AT_MIPS_abstract_name 0x2009" +This attribute only appears in a DA_TAG_inlined_subroutine DIE. +The value of this attribute is a string. +When IPA inlines a routine and the abstract origin is +in another compilation unit, there is a problem with putting +in a reference, since the ordering and timing of the +creation of references is unpredicatable with reference to +the DIE and compilation unit the reference refers to. +.P +Since there may be NO ordering of the compilation units that +allows a correct reference to be done without some kind of patching, +and since even getting the information from one place to another +is a problem, the compiler simply passes the problem on to the debugger. +.P +The debugger must match the DW_AT_MIPS_abstract_name +in the concrete +inlined instance DIE +with the DW_AT_MIPS_abstract_name +in the abstract inlined subroutine DIE. +.P +A dwarf-consumer-centric view of this and other inline +issues could be expressed as follows: +.nf +If DW_TAG_subprogram + If has DW_AT_inline is abstract instance root + If has DW_AT_abstract_origin, is out-of-line instance + of function (need abstract origin for some data) + (abstract root in same CU (conceptually anywhere + a ref can reach, but reaching outside of CU is + a problem for ipa: see DW_AT_MIPS_abstract_name)) + If has DW_AT_MIPS_abstract_name is abstract instance + root( must have DW_AT_inline) and this name is used to + match with the abstract root + +If DW_TAG_inline_subroutine + Is concrete inlined subprogram instance. + If has DW_AT_abstract_origin, it is a CU-local inline. + If it has DW_AT_MIPS_abstract_name it is an + inline whose abstract root is in another file (CU). +.fi + +.H 2 "DW_AT_MIPS_clone_origin 0x200a" +This attribute appears only in a cloned subroutine. +The procedure is cloned from the same compilation unit. +The value of this attribute is a reference to +the original routine in this compilation unit. +.P +The 'original' routine means the routine which has all the +original code. The cloned routines will always have +been 'specialized' by IPA. +A routine with DW_AT_MIPS_clone_origin +will also have the DW_CC_nocall value of the DW_AT_calling_convention +attribute. + +.H 2 "DW_AT_MIPS_has_inlines 0x200b" +This attribute may appear in a DW_TAG_subprogram DIE. +If present and it has the value True, then the subprogram +has inlined functions somewhere in the body. +.P +By default, at startup, the debugger may not look for +inlined functions in scopes inside the outer function. +.P +This is a hint to the debugger to look for the inlined functions +so the debugger can set breakpoints on these in case the user +requests 'stop in foo' and foo is inlined. +.H 2 "DW_AT_MIPS_stride_byte 0x200c" +Created for f90 pointer and assumed shape +arrays. +Used in the MIPSpro 7.2 (7.2.1 etc) compilers. +A variant of DW_AT_MIPS_stride. +This stride is interpreted as a byte count. +Used for integer*1 and character arrays +and arrays of derived type +whose components are all character. +.H 2 "DW_AT_MIPS_stride_elem 0x200d" +Created for f90 pointer and assumed shape +arrays. +Used in the MIPSpro 7.2 (7.2.1 etc) compilers. +A variant of DW_AT_MIPS_stride. +This stride is interpreted as a byte-pair (2 byte) count. +Used for integer*2 arrays. +.H 2 "DW_AT_MIPS_ptr_dopetype 0x200e" +See following. +.H 2 "DW_AT_MIPS_allocatable_dopetype 0x200f" +See following. +.H 2 "DW_AT_MIPS_assumed_shape_dopetype 0x2010" +DW_AT_MIPS_assumed_shape_dopetype, DW_AT_MIPS_allocatable_dopetype, +and DW_AT_MIPS_ptr_dopetype have an attribute value +which is a reference to a Fortran 90 Dope Vector. +These attributes are introduced in MIPSpro7.3. +They only apply to f90 arrays (where they are +needed to describe arrays never properly described +before in debug information). +C, C++, f77, and most f90 arrays continue to be described +in standard dwarf. +.P +The distinction between these three attributes is the f90 syntax +distinction: keywords 'pointer' and 'allocatable' with the absence +of these keywords on an assumed shape array being the third case. +.P +A "Dope Vector" is a struct (C struct) which describes +a dynamically-allocatable array. +In objects with full debugging the C struct will be +in the dwarf information (of the f90 object, represented like C). +A debugger will use the link to find the main struct DopeVector +and will use that information to decode the dope vector. +At the outer allocatable/assumed-shape/pointer +the DW_AT_location points at the dope vector (so debugger +calculations use that as a base). +.H 2 "Overview of debugger use of dope vectors" +Fundamentally, we build two distinct +representations of the arrays and pointers. +One, in dwarf, represents the statically-representable +information (the types and +variable/type-names, without type size information). +The other, using dope vectors in memory, represents +the run-time data of sizes. +A debugger must process the two representations +in parallel (and merge them) to deal with user expressions in +a debugger. +.H 2 "Example f90 code for use in explanation" +[Note +We want dwarf output with *exactly* +this little (arbitrary) example. +Not yet available. +end Note] +Consider the following code. +.nf + type array_ptr + real :: myvar + real, dimension (:), pointer :: ap + end type array_ptr + + type (array_ptr), allocatable, dimension (:) :: arrays + + allocate (arrays(20)) + do i = 1,20 + allocate (arrays(i)%ap(i)) + end do +.fi +arrays is an allocatable array (1 dimension) whose size is +not known at compile time (it has +a Dope Vector). At run time, the +allocate statement creats 20 array_ptr dope vectors +and marks the base arrays dopevector as allocated. +The myvar variable is just there to add complexity to +the example :-) +.nf +In the loop, arrays(1)%ap(1) + is allocated as a single element array of reals. +In the loop, arrays(2)%ap(2) + is allocated as an array of two reals. +... +In the loop, arrays(20)%ap(20) + is allocated as an array of twenty reals. +.fi +.H 2 "the problem with standard dwarf and this example" +.sp +In dwarf, there is no way to find the array bounds of arrays(3)%ap, +for example, (which are 1:3 in f90 syntax) +since any location expression in an ap array lower bound +attribute cannot involve the 3 (the 3 is known at debug time and +does not appear in the running binary, so no way for the +location expression to get to it). +And of course the 3 must actually index across the array of +dope vectors in 'arrays' in our implementation, but that is less of +a problem than the problem with the '3'. +.sp +Plus dwarf has no way to find the 'allocated' flag in the +dope vector (so the debugger can know when the allocate is done +for a particular arrays(j)%ap). +.sp +Consequently, the calculation of array bounds and indices +for these dynamically created f90 arrays +is now pushed of into the debugger, which must know the +field names and usages of the dope vector C structure and +use the field offsets etc to find data arrays. +C, C++, f77, and most f90 arrays continue to be described +in standard dwarf. +At the outer allocatable/assumed-shape/pointer +the DW_AT_location points at the dope vector (so debugger +calculations use that as a base). +.P +It would have been nice to design a dwarf extension +to handle the above problems, but +the methods considered to date were not +any more consistent with standard dwarf than +this dope vector centric approach: essentially just +as much work in the debugger appeared necessary either way. +A better (more dwarf-ish) +design would be welcome information. + +.H 2 "A simplified sketch of the dwarf information" +[Note: +Needs to be written. +end Note] + +.H 2 "A simplified sketch of the dope vector information" +[Note: +This one is simplified. +Details left out that should be here. Amplify. +end Note] +This is an overly simplified version of a dope vector, +presented as an initial hint. +Full details presented later. +.nf +struct simplified{ + void *base; // pointer to the data this describes + long el_len; + int assoc:1 + int ptr_alloc:1 + int num_dims:3; + struct dims_s { + long lb; + long ext; + long str_m; + } dims[7]; +}; +.fi +Only 'num_dims' elements of dims[] are actually used. + +.H 2 "The dwarf information" + +Here is dwarf information from the compiler for +the example above, as printed by dwarfdump(1) +.nf +[Note: +The following may not be the test. +Having field names with '.' in the name is +not such a good idea, as it conflicts with the +use of '.' in dbx extended naming. +Something else, like _$, would be much easier +to work with in dbx (customers won't care about this, +for the most part, +but folks working on dbx will, and in those +rare circumstances when a customer cares, +the '.' will be a real problem in dbx.). +Note that to print something about .base., in dbx one +would have to do + whatis `.base.` +where that is the grave accent, or back-quote I am using. +With extended naming one do + whatis `.dope.`.`.base.` +which is hard to type and hard to read. +end Note] + +<2>< 388> DW_TAG_array_type + DW_AT_name .base. + DW_AT_type <815> + DW_AT_declaration yes(1) +<3>< 401> DW_TAG_subrange_type + DW_AT_lower_bound 0 + DW_AT_upper_bound 0 +<2>< 405> DW_TAG_pointer_type + DW_AT_type <388> + DW_AT_byte_size 4 + DW_AT_address_class 0 +<2>< 412> DW_TAG_structure_type + DW_AT_name .flds. + DW_AT_byte_size 28 +<3>< 421> DW_TAG_member + DW_AT_name el_len + DW_AT_type <815> + DW_AT_data_member_location DW_OP_consts 0 +<3>< 436> DW_TAG_member + DW_AT_name assoc + DW_AT_type <841> + DW_AT_byte_size 0 + DW_AT_bit_offset 0 + DW_AT_bit_size 1 + DW_AT_data_member_location DW_OP_consts 4 +<3>< 453> DW_TAG_member + DW_AT_name ptr_alloc + DW_AT_type <841> + DW_AT_byte_size 0 + DW_AT_bit_offset 1 + DW_AT_bit_size 1 + DW_AT_data_member_location DW_OP_consts 4 +<3>< 474> DW_TAG_member + DW_AT_name p_or_a + DW_AT_type <841> + DW_AT_byte_size 0 + DW_AT_bit_offset 2 + DW_AT_bit_size 2 + DW_AT_data_member_location DW_OP_consts 4 +<3>< 492> DW_TAG_member + DW_AT_name a_contig + DW_AT_type <841> + DW_AT_byte_size 0 + DW_AT_bit_offset 4 + DW_AT_bit_size 1 + DW_AT_data_member_location DW_OP_consts 4 +<3>< 532> DW_TAG_member + DW_AT_name num_dims + DW_AT_type <841> + DW_AT_byte_size 0 + DW_AT_bit_offset 29 + DW_AT_bit_size 3 + DW_AT_data_member_location DW_OP_consts 8 +<3>< 572> DW_TAG_member + DW_AT_name type_code + DW_AT_type <841> + DW_AT_byte_size 0 + DW_AT_bit_offset 0 + DW_AT_bit_size 32 + DW_AT_data_member_location DW_OP_consts 16 +<3>< 593> DW_TAG_member + DW_AT_name orig_base + DW_AT_type <841> + DW_AT_data_member_location DW_OP_consts 20 +<3>< 611> DW_TAG_member + DW_AT_name orig_size + DW_AT_type <815> + DW_AT_data_member_location DW_OP_consts 24 +<2>< 630> DW_TAG_structure_type + DW_AT_name .dope_bnd. + DW_AT_byte_size 12 +<3>< 643> DW_TAG_member + DW_AT_name lb + DW_AT_type <815> + DW_AT_data_member_location DW_OP_consts 0 +<3>< 654> DW_TAG_member + DW_AT_name ext + DW_AT_type <815> + DW_AT_data_member_location DW_OP_consts 4 +<3>< 666> DW_TAG_member + DW_AT_name str_m + DW_AT_type <815> + DW_AT_data_member_location DW_OP_consts 8 +<2>< 681> DW_TAG_array_type + DW_AT_name .dims. + DW_AT_type <630> + DW_AT_declaration yes(1) +<3>< 694> DW_TAG_subrange_type + DW_AT_lower_bound 0 + DW_AT_upper_bound 0 +<2>< 698> DW_TAG_structure_type + DW_AT_name .dope. + DW_AT_byte_size 44 +<3>< 707> DW_TAG_member + DW_AT_name base + DW_AT_type <405> + DW_AT_data_member_location DW_OP_consts 0 +<3>< 720> DW_TAG_member + DW_AT_name .flds + DW_AT_type <412> + DW_AT_data_member_location DW_OP_consts 4 +<3>< 734> DW_TAG_member + DW_AT_name .dims. + DW_AT_type <681> + DW_AT_data_member_location DW_OP_consts 32 +<2>< 750> DW_TAG_variable + DW_AT_type <815> + DW_AT_location DW_OP_fbreg -32 + DW_AT_artificial yes(1) +<2>< 759> DW_TAG_variable + DW_AT_type <815> + DW_AT_location DW_OP_fbreg -28 + DW_AT_artificial yes(1) +<2>< 768> DW_TAG_variable + DW_AT_type <815> + DW_AT_location DW_OP_fbreg -24 + DW_AT_artificial yes(1) +<2>< 777> DW_TAG_array_type + DW_AT_type <815> + DW_AT_declaration yes(1) +<3>< 783> DW_TAG_subrange_type + DW_AT_lower_bound <750> + DW_AT_count <759> + DW_AT_MIPS_stride <768> +<2>< 797> DW_TAG_variable + DW_AT_decl_file 1 + DW_AT_decl_line 1 + DW_AT_name ARRAY + DW_AT_type <698> + DW_AT_location DW_OP_fbreg -64 DW_OP_deref +<1>< 815> DW_TAG_base_type + DW_AT_name INTEGER_4 + DW_AT_encoding DW_ATE_signed + DW_AT_byte_size 4 +<1>< 828> DW_TAG_base_type + DW_AT_name INTEGER_8 + DW_AT_encoding DW_ATE_signed + DW_AT_byte_size 8 +<1>< 841> DW_TAG_base_type + DW_AT_name INTEGER*4 + DW_AT_encoding DW_ATE_unsigned + DW_AT_byte_size 4 +<1>< 854> DW_TAG_base_type + DW_AT_name INTEGER*8 + DW_AT_encoding DW_ATE_unsigned + DW_AT_byte_size 8 + +.fi +.H 2 "The dope vector structure details" +A dope vector is the following C struct, "dopevec.h". +Not all the fields are of use to a debugger. +It may be that not all fields will show up +in the f90 dwarf (since not all are of interest to debuggers). +.nf +[Note: +Need details on the use of each field. +And need to know which are really 32 bits and which +are 32 or 64. +end Note] +The following +struct +is a representation of all the dope vector fields. +It suppresses irrelevant detail and may not +exactly match the layout in memory (a debugger must +examine the dwarf to find the fields, not +compile this structure into the debugger!). +.nf +struct .dope. { + void *base; // pointer to data + struct .flds. { + long el_len; // length of element in bytes? + unsigned int assoc:1; //means? + unsigned int ptr_alloc:1; //means? + unsigned int p_or_a:2; //means? + unsigned int a_contig:1; // means? + unsigned int num_dims: 3; // 0 thru 7 + unsigned int type_code:32; //values? + unsigned int orig_base; //void *? means? + long orig_size; // means? + } .flds; + + struct .dope_bnd. { + long lb ; // lower bound + long ext ; // means? + long str_m; // means? + } .dims[7]; +} +.fi + +.H 2 "DW_AT_MIPS_assumed_size 0x2011" +This flag was invented to deal with f90 arrays. +For example: + +.nf + pointer (rptr, axx(1)) + pointer (iptr, ita(*)) + rptr = malloc (100*8) + iptr = malloc (100*4) +.fi + +This flag attribute has the value 'yes' (true, on) if and only if +the size is unbounded, as iptr is. +Both may show an explicit upper bound of 1 in the dwarf, +but this flag notifies the debugger that there is explicitly +no user-provided size. + +So if a user asks for a printout of the rptr allocated +array, the default will be of a single entry (as +there is a user slice bound in the source). +In contrast, there is no explicit upper bound on the iptr +(ita) array so the default slice will use the current bound +(a value calculated from the malloc size, see the dope vector). + +Given explicit requests, more of rptr(axx) can me shown +than the default. + +.H 1 "Line information and Source Position" +DWARF does not define the meaning of the term 'source statement'. +Nor does it define any way to find the first user-written +executable code in a function. +.P +It does define that a source statement has a file name, +a line number, and a column position (see Sec 6.2, Line Number +Information of the Dwarf Version 2 document). +We will call those 3 source coordinates a 'source position' +in this document. We'll try not to accidentally call the +source position a 'line number' since that is ambiguous +as to what it means. + +.H 2 "Definition of Statement" +.P +A function prolog is a statement. +.P +A C, C++, Pascal, or Fortran statement is a statement. +.P +Each initialized local variable in C,C++ is a statement +in that its initialization generates a source position. +This means that + x =3, y=4; +is two statements. +.P +For C, C++: +The 3 parts a,b,c in for(a;b;c) {d;} are individual statements. +The condition portion of a while() and do {} while() is +a statement. (of course d; can be any number of statements) +.P +For Fortran, the controlling expression of a DO loop is a statement. +Is a 'continue' statement in Fortran a DWARF statement? +.P +Each function return, whether user coded or generated by the +compiler, is a statement. This is so one can step over (in +a debugger) the final user-coded statement +(exclusive of the return statement if any) in a function +wile not leaving the function scope. +.P + +.H 2 "Finding The First User Code in a Function" + +.nf +Consider: +int func(int a) +{ /* source position 1 */ + float b = a; /* source position 2 */ + int x; + x = b + 2; /* source position 3 */ +} /* source position 4 */ +.fi +.P +The DIE for a function gives the address range of the function, +including function prolog(s) and epilog(s) +.P +Since there is no scope block for the outer user scope of a +function (and thus no beginning address range for the outer +user scope: the DWARF committee explicitly rejected the idea +of having a user scope block) +it is necessary to use the source position information to find +the first user-executable statement. +.P +This means that the user code for a function must be presumed +to begin at the code location of the second source position in +the function address range. +.P +If a function has exactly one source position, the function +presumably consists solely of a return. +.P +If a function has exactly two source positions, the function +may consist of a function prolog and a return or a single user +statement and a return (there may be no prolog code needed in a +leaf function). In this case, there is no way to be sure which +is the first source position of user code, so the rule is to +presume that the first address is user code. +.P +If a function consists of 3 or more source positions, one +should assume that the first source position is function prolog and +the second is the first user executable code. + +.H 2 "Using debug_frame Information to find first user statement" +In addition to the line information, the debug_frame information +can be +useful in determining the first user source line. +.P +Given that a function has more than 1 source position, +Find the code location of the second source position, then +examine the debug_frame information to determine if the Canonical +Frame Address (cfa) is updated before the second source position +code location. +If the cfa is updated, then one can be pretty sure that the +code for the first source position is function prolog code. +.P +Similarly, if the cfa is restored in the code for +a source position, the source position is likely to +represent a function exit block. + +.H 2 "Debugger Use Of Source Position" +Command line debuggers, such as dbx and gdb, will ordinarily +want to consider multiple statements on one line to be a single +statement: doing otherwise is distressing to users since it +causes a 'step' command to appear to have no effect. +.P +An exception for command line debuggers is in determining the +first user statement: as detailed above, there one wants to +consider the full source position and will want to consider +the function return a separate statement. It is difficult to +make the function return a separate statement 'step' reliably +however if a function is coded all on one line or if the last +line of user code before the return is on the same line as the +return. +.P +A graphical debugger has none of these problems if it simply +highlights the portion of the line being executed. In that +case, stepping will appear natural even stepping within a +line. +.H 1 "Known Bugs" +Up through at least MIPSpro7.2.1 +the compiler has been emitting form DW_FORM_DATA1,2, or 4 +for DW_AT_const_value in DW_TAG_enumerator. +And dwarfdump and debuggers have read this with dwarf_formudata() +or form_sdata() and gotten some values incorrect. +For example, a value of 128 was printed by debuggers as a negative value. +Since dwarfdump and the compilers were not written to use the +value the same way, their output differed. +For negative enumerator values the compiler has been emitting 32bit values +in a DW_FORM_DATA4. +The compiler should probably be emitting a DW_FORM_sdata for +enumerator values. +And consumers of enumerator values should then call form_sdata(). +However, right now, debuggers should call form_udata() and only if +it fails, call form_sdata(). +Anything else will break backward compatibility with +the objects produced earlier. +.SK +.S +.TC 1 1 4 +.CS diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/mips_extensions.pdf Binary file tools/elf4rom/libs/dwarf-20071209/libdwarf/mips_extensions.pdf has changed diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_alloc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_alloc.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,187 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2002,2007 Sun Microsystems, Inc. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "pro_incl.h" +#ifdef HAVE_STDLIB_H +#include +#endif /* HAVE_STDLIB_H */ +#ifdef HAVE_STRING_H +#include +#endif /* HAVE_STRING_H */ +#include + +/* + When each block is allocated, there is a two-word structure + allocated at the beginning so the block can go on a list. + The address returned is the address *after* the two pointers + at the start. But this allows us to be given a pointer to + a generic block, and go backwards to find the list-node. Then + we can remove this block from it's list without the need to search + through a linked list in order to remove the node. It also allows + us to 'delete' a memory block without needing the dbg structure. + We still need the dbg structure on allocation so that we know which + linked list to add the block to. + + Only the allocation of the dbg structure itself cannot use _dwarf_p_get_alloc. + That structure should be set up by hand, and the two list pointers + should be initialized to point at the node itself. That initializes + the doubly linked list. +*/ + +#define LIST_TO_BLOCK(lst) ((void*) (((char *)lst) + sizeof(memory_list_t))) +#define BLOCK_TO_LIST(blk) ((memory_list_t*) (((char*)blk) - sizeof(memory_list_t))) + + +/* + dbg should be NULL only when allocating dbg itself. In that + case we initialize it to an empty circular doubly-linked list. +*/ + +Dwarf_Ptr +_dwarf_p_get_alloc(Dwarf_P_Debug dbg, Dwarf_Unsigned size) +{ + void *sp; + memory_list_t *lp = NULL; + memory_list_t *dbglp = NULL; + memory_list_t *nextblock = NULL; + + /* alloc control struct and data block together for performance reasons */ + lp = (memory_list_t *) malloc(size + sizeof(memory_list_t)); + if (lp == NULL) { + /* should throw an error */ + return NULL; + } + + /* point to 'size' bytes just beyond lp struct */ + sp = LIST_TO_BLOCK(lp); + memset(sp, 0, size); + + if (dbg == NULL) { + lp->next = lp->prev = lp; + } else { + /* I always have to draw a picture to understand this part. */ + + dbglp = BLOCK_TO_LIST(dbg); + nextblock = dbglp->next; + + /* Insert between dbglp and nextblock */ + dbglp->next = lp; + lp->prev = dbglp; + lp->next = nextblock; + nextblock->prev = lp; + } + + return sp; +} + +/* + This routine is only here in case a caller of an older version of the + library is calling this for some reason. + We will clean up any stray blocks when the session is closed. + No need to remove this block. In theory the user might be depending on the fact + that we used to just 'free' this. In theory they might also be + passing a block that they got from libdwarf. So we don't know if we + should try to remove this block from our global list. Safest just to + do nothing at this point. + + !!! + This function is deprecated! Don't call it inside libdwarf or outside of it. + !!! +*/ + +void +dwarf_p_dealloc(Dwarf_Small * ptr) +{ + return; +} + +/* + The dbg structure is not needed here anymore. +*/ + +void +_dwarf_p_dealloc(Dwarf_P_Debug dbg, Dwarf_Small * ptr) /* ARGSUSED */ +{ + memory_list_t *lp; + lp = BLOCK_TO_LIST(ptr); + + /* + Remove from a doubly linked, circular list. + Read carefully, use a white board if necessary. + If this is an empty list, the following statements are no-ops, and + will write to the same memory location they read from. + This should only happen when we deallocate the dbg structure itself. + */ + + lp->prev->next = lp->next; + lp->next->prev = lp->prev; + + free((void*)lp); +} + + +/* + This routine deallocates all the nodes on the dbg list, + and then deallocates the dbg structure itself. +*/ + +void +_dwarf_p_dealloc_all(Dwarf_P_Debug dbg) +{ + memory_list_t *dbglp; + + if (dbg == NULL) { + /* should throw an error */ + return; + } + + dbglp = BLOCK_TO_LIST(dbg); + while (dbglp->next != dbglp) { + _dwarf_p_dealloc(dbg, LIST_TO_BLOCK(dbglp->next)); + } + if (dbglp->next != dbglp || + dbglp->prev != dbglp) { + + /* should throw error */ + /* For some reason we couldn't free all the blocks? */ + return; + } + _dwarf_p_dealloc(NULL, (void*)dbg); +} + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_alloc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_alloc.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,42 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +Dwarf_Ptr _dwarf_p_get_alloc(Dwarf_P_Debug, Dwarf_Unsigned); + +void _dwarf_p_dealloc(Dwarf_P_Debug dbg, Dwarf_Small * ptr); + +void _dwarf_p_dealloc_all(Dwarf_P_Debug dbg); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_arange.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_arange.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,337 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#endif +#include "pro_incl.h" +#include "pro_arange.h" +#include "pro_section.h" +#include "pro_reloc.h" + + + +/* + This function adds another address range + to the list of address ranges for the + given Dwarf_P_Debug. It returns 0 on error, + and 1 otherwise. +*/ +Dwarf_Unsigned +dwarf_add_arange(Dwarf_P_Debug dbg, + Dwarf_Addr begin_address, + Dwarf_Unsigned length, + Dwarf_Signed symbol_index, Dwarf_Error * error) +{ + return dwarf_add_arange_b(dbg, begin_address, length, symbol_index, + /* end_symbol_index */ 0, + /* offset_from_end_sym */ 0, + error); +} + +/* + This function adds another address range + to the list of address ranges for the + given Dwarf_P_Debug. It returns 0 on error, + and 1 otherwise. +*/ +Dwarf_Unsigned +dwarf_add_arange_b(Dwarf_P_Debug dbg, + Dwarf_Addr begin_address, + Dwarf_Unsigned length, + Dwarf_Unsigned symbol_index, + Dwarf_Unsigned end_symbol_index, + Dwarf_Addr offset_from_end_sym, Dwarf_Error * error) +{ + Dwarf_P_Arange arange; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return (0); + } + + arange = (Dwarf_P_Arange) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Arange_s)); + if (arange == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (0); + } + + arange->ag_begin_address = begin_address; + arange->ag_length = length; + arange->ag_symbol_index = symbol_index; + arange->ag_end_symbol_index = end_symbol_index; + arange->ag_end_symbol_offset = offset_from_end_sym; + + if (dbg->de_arange == NULL) + dbg->de_arange = dbg->de_last_arange = arange; + else { + dbg->de_last_arange->ag_next = arange; + dbg->de_last_arange = arange; + } + dbg->de_arange_count++; + + return (1); +} + + +int +_dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + /* Total num of bytes in .debug_aranges section. */ + Dwarf_Unsigned arange_num_bytes; + + /* + Adjustment to align the start of the actual address ranges on a + boundary aligned with twice the address size. */ + Dwarf_Small remainder; + + /* Total number of bytes excluding the length field. */ + Dwarf_Unsigned adjusted_length; + + /* Points to first byte of .debug_aranges buffer. */ + Dwarf_Small *arange; + + /* Fills in the .debug_aranges buffer. */ + Dwarf_Small *arange_ptr; + + /* Scans the list of address ranges provided by user. */ + Dwarf_P_Arange given_arange; + + /* Used to fill in 0. */ + const Dwarf_Signed big_zero = 0; + + int extension_word_size = dbg->de_64bit_extension ? 4 : 0; + int uword_size = dbg->de_offset_size; + int upointer_size = dbg->de_pointer_size; + int res; + + + /* ***** BEGIN CODE ***** */ + + /* Size of the .debug_aranges section header. */ + arange_num_bytes = extension_word_size + uword_size + /* Size + of + length + field. + */ + sizeof(Dwarf_Half) + /* Size of version field. */ + uword_size + /* Size of .debug_info offset. */ + sizeof(Dwarf_Small) + /* Size of address size field. */ + sizeof(Dwarf_Small); /* Size of segment size field. */ + + /* + Adjust the size so that the set of aranges begins on a boundary + that aligned with twice the address size. This is a Libdwarf + requirement. */ + remainder = arange_num_bytes % (2 * upointer_size); + if (remainder != 0) + arange_num_bytes += (2 * upointer_size) - remainder; + + + /* Add the bytes for the actual address ranges. */ + arange_num_bytes += upointer_size * 2 * (dbg->de_arange_count + 1); + + GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_ARANGES], + arange, (unsigned long) arange_num_bytes, error); + arange_ptr = arange; + if (arange == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (0); + } + if (extension_word_size) { + Dwarf_Word x = DISTINGUISHED_VALUE; + + WRITE_UNALIGNED(dbg, (void *) arange_ptr, + (const void *) &x, + sizeof(x), extension_word_size); + arange_ptr += extension_word_size; + } + + /* Write the total length of .debug_aranges section. */ + adjusted_length = arange_num_bytes - uword_size + - extension_word_size; + { + Dwarf_Unsigned du = adjusted_length; + + WRITE_UNALIGNED(dbg, (void *) arange_ptr, + (const void *) &du, sizeof(du), uword_size); + arange_ptr += uword_size; + } + + /* Write the version as 2 bytes. */ + { + Dwarf_Half verstamp = CURRENT_VERSION_STAMP; + + WRITE_UNALIGNED(dbg, (void *) arange_ptr, + (const void *) &verstamp, + sizeof(verstamp), sizeof(Dwarf_Half)); + arange_ptr += sizeof(Dwarf_Half); + } + + + /* Write the .debug_info offset. This is always 0. */ + WRITE_UNALIGNED(dbg, (void *) arange_ptr, + (const void *) &big_zero, + sizeof(big_zero), uword_size); + arange_ptr += uword_size; + + { + unsigned long count = dbg->de_arange_count + 1; + int res; + + if (dbg->de_reloc_pair) { + count = (3 * dbg->de_arange_count) + 1; + } + /* the following is a small optimization: not needed for + correctness */ + res = _dwarf_pro_pre_alloc_n_reloc_slots(dbg, + DEBUG_ARANGES, count); + if (res != DW_DLV_OK) { + { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (0); + } + } + } + + /* reloc for .debug_info */ + res = dbg->de_reloc_name(dbg, + DEBUG_ARANGES, + extension_word_size + + uword_size + sizeof(Dwarf_Half), + dbg->de_sect_name_idx[DEBUG_INFO], + dwarf_drt_data_reloc, uword_size); + + /* Write the size of addresses. */ + *arange_ptr = dbg->de_pointer_size; + arange_ptr++; + + /* + Write the size of segment addresses. This is zero for MIPS + architectures. */ + *arange_ptr = 0; + arange_ptr++; + + /* + Skip over the padding to align the start of the actual address + ranges to twice the address size. */ + if (remainder != 0) + arange_ptr += (2 * upointer_size) - remainder; + + + + + + /* The arange address, length are pointer-size fields of the target + machine. */ + for (given_arange = dbg->de_arange; given_arange != NULL; + given_arange = given_arange->ag_next) { + + /* Write relocation record for beginning of address range. */ + res = dbg->de_reloc_name(dbg, DEBUG_ARANGES, arange_ptr - arange, /* r_offset + */ + (long) given_arange->ag_symbol_index, + dwarf_drt_data_reloc, upointer_size); + if (res != DW_DLV_OK) { + { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (0); + } + } + + /* Copy beginning address of range. */ + WRITE_UNALIGNED(dbg, (void *) arange_ptr, + (const void *) &given_arange->ag_begin_address, + sizeof(given_arange->ag_begin_address), + upointer_size); + arange_ptr += upointer_size; + + if (dbg->de_reloc_pair && + given_arange->ag_end_symbol_index != 0 && + given_arange->ag_length == 0) { + /* symbolic reloc, need reloc for length What if we really + know the length? If so, should use the other part of + 'if'. */ + Dwarf_Unsigned val; + + res = dbg->de_reloc_pair(dbg, DEBUG_ARANGES, arange_ptr - arange, /* r_offset + */ + given_arange->ag_symbol_index, + given_arange->ag_end_symbol_index, + dwarf_drt_first_of_length_pair, + upointer_size); + if (res != DW_DLV_OK) { + { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (0); + } + } + + /* arrange pre-calc so assem text can do .word end - begin + + val (gets val from stream) */ + val = given_arange->ag_end_symbol_offset - + given_arange->ag_begin_address; + WRITE_UNALIGNED(dbg, (void *) arange_ptr, + (const void *) &val, + sizeof(val), upointer_size); + arange_ptr += upointer_size; + + } else { + /* plain old length to copy, no relocation at all */ + WRITE_UNALIGNED(dbg, (void *) arange_ptr, + (const void *) &given_arange->ag_length, + sizeof(given_arange->ag_length), + upointer_size); + arange_ptr += upointer_size; + } + } + + WRITE_UNALIGNED(dbg, (void *) arange_ptr, + (const void *) &big_zero, + sizeof(big_zero), upointer_size); + + arange_ptr += upointer_size; + WRITE_UNALIGNED(dbg, (void *) arange_ptr, + (const void *) &big_zero, + sizeof(big_zero), upointer_size); + return (int) dbg->de_n_debug_sect; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_arange.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_arange.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,62 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + +/* + If ag_end_symbol_index is zero, + ag_length must be known and non-zero. + + + Deals with length being known costant or fr + assembler output, not known. + +*/ + +struct Dwarf_P_Arange_s { + Dwarf_Addr ag_begin_address; /* known address or for + symbolic assem output, + offset of symbol */ + Dwarf_Addr ag_length; /* zero or address or offset */ + Dwarf_Unsigned ag_symbol_index; + + Dwarf_P_Arange ag_next; + + Dwarf_Unsigned ag_end_symbol_index; /* zero or index/id of end + symbol */ + Dwarf_Addr ag_end_symbol_offset; /* known address or for + symbolic assem output, + offset of end symbol */ + +}; diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_die.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_die.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,435 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#include "pro_incl.h" +#include "pro_die.h" + +#ifndef R_MIPS_NONE +#define R_MIPS_NONE 0 +#endif + +/* adds an attribute to a die */ +void _dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr); + +/*---------------------------------------------------------------------------- + This function creates a new die. + tag: tag of the new die to be created + parent,child,left,right: specify neighbors of the new die. Only + one of these may be non-null +-----------------------------------------------------------------------------*/ +Dwarf_P_Die +dwarf_new_die(Dwarf_P_Debug dbg, + Dwarf_Tag tag, + Dwarf_P_Die parent, + Dwarf_P_Die child, + Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error) +{ + Dwarf_P_Die new_die, ret_die; + + new_die = (Dwarf_P_Die) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Die_s)); + if (new_die == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_ALLOC, + (Dwarf_P_Die) DW_DLV_BADADDR); + } + new_die->di_parent = NULL; + new_die->di_left = NULL; + new_die->di_right = NULL; + new_die->di_child = NULL; + new_die->di_tag = tag; + new_die->di_dbg = dbg; + new_die->di_marker = 0; + ret_die = + dwarf_die_link(new_die, parent, child, left, right, error); + return ret_die; +} + +/*---------------------------------------------------------------------------- + This function links up a die to specified neighbors + parent,child,left,right: specify neighbors of the new die. Only + one of these may be non-null +-----------------------------------------------------------------------------*/ +Dwarf_P_Die +dwarf_die_link(Dwarf_P_Die new_die, + Dwarf_P_Die parent, + Dwarf_P_Die child, + Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error) +{ + int n_nulls; /* to count # of non null neighbors */ + Dwarf_P_Die orig; + + n_nulls = 0; + if (parent != NULL) { + n_nulls++; + if (new_die->di_parent != NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_LINK_LOOP, + (Dwarf_P_Die) DW_DLV_BADADDR); + } + new_die->di_parent = parent; + if (parent->di_child) { /* got to traverse the child's siblings + */ + Dwarf_P_Die curdie; + + curdie = parent->di_child; + orig = curdie; + while (curdie->di_right) { + curdie = curdie->di_right; + if (curdie == orig || curdie == curdie->di_right) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_LINK_LOOP, + (Dwarf_P_Die) DW_DLV_BADADDR); + } + } + curdie->di_right = new_die; /* attach to sibling list */ + new_die->di_left = curdie; /* back pointer */ + } else + parent->di_child = new_die; + } + if (child != NULL) { + n_nulls++; + new_die->di_child = child; + if (child->di_parent) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS, + (Dwarf_P_Die) DW_DLV_BADADDR); + } else { + child->di_parent = new_die; + } + } + if (left != NULL) { + n_nulls++; + new_die->di_left = left; + if (left->di_right) /* there's already a right sibl, lets + insert */ + new_die->di_right = left->di_right; + left->di_right = new_die; + /* add parent pointer */ + if (new_die->di_parent) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS, + (Dwarf_P_Die) DW_DLV_BADADDR); + } else + new_die->di_parent = left->di_parent; + } + if (right != NULL) { + n_nulls++; + new_die->di_right = right; + if (right->di_left) /* left sibl exists, try inserting */ + new_die->di_left = right->di_left; + right->di_left = new_die; + if (new_die->di_parent) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS, + (Dwarf_P_Die) DW_DLV_BADADDR); + } else + new_die->di_parent = right->di_parent; + } + if (n_nulls > 1) { /* multiple neighbors, error */ + DWARF_P_DBG_ERROR(NULL, DW_DLE_EXTRA_NEIGHBORS, + (Dwarf_P_Die) DW_DLV_BADADDR); + } + return new_die; + +} + +Dwarf_Unsigned +dwarf_add_die_marker(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + Dwarf_Unsigned marker, + Dwarf_Error * error) +{ + if (die == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT); + } + die->di_marker = marker; + return 0; +} + + +Dwarf_Unsigned +dwarf_get_die_marker(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + Dwarf_Unsigned * marker, + Dwarf_Error * error) +{ + if (die == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT); + } + *marker = die->di_marker; + return 0; +} + + + + +/*---------------------------------------------------------------------------- + This function adds a die to dbg struct. It should be called using + the root of all the dies. +-----------------------------------------------------------------------------*/ +Dwarf_Unsigned +dwarf_add_die_to_debug(Dwarf_P_Debug dbg, + Dwarf_P_Die first_die, Dwarf_Error * error) +{ + if (first_die == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT); + } + if (first_die->di_tag != DW_TAG_compile_unit) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_TAG, DW_DLV_NOCOUNT); + } + dbg->de_dies = first_die; + return 0; +} + +int +_dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg, + Dwarf_P_Die first_die, Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + int uwordb_size = dbg->de_offset_size; + + /* Add AT_stmt_list attribute */ + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_NOCOUNT); + } + + new_attr->ar_attribute = DW_AT_stmt_list; + new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form; + new_attr->ar_rel_type = dbg->de_offset_reloc; + + new_attr->ar_nbytes = uwordb_size; + new_attr->ar_next = NULL; + new_attr->ar_reloc_len = uwordb_size; + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(dbg, uwordb_size); + if (new_attr->ar_data == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT); + } + { + Dwarf_Unsigned du = 0; + + WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data, + (const void *) &du, sizeof(du), uwordb_size); + } + + _dwarf_pro_add_at_to_die(first_die, new_attr); + return 0; +} + +/*----------------------------------------------------------------------------- + Add AT_name attribute to die +------------------------------------------------------------------------------*/ +Dwarf_P_Attribute +dwarf_add_AT_name(Dwarf_P_Die die, char *name, Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + + if (die == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, + (Dwarf_P_Attribute) DW_DLV_BADADDR); + } + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(die->di_dbg,sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, + (Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + /* fill in the information */ + new_attr->ar_attribute = DW_AT_name; + /* assume that form is string, no debug_str yet */ + new_attr->ar_attribute_form = DW_FORM_string; + new_attr->ar_nbytes = strlen(name) + 1; + new_attr->ar_next = NULL; + new_attr->ar_reloc_len = 0; + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(die->di_dbg, strlen(name)+1); + if (new_attr->ar_data == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_STRING_ALLOC, + (Dwarf_P_Attribute) DW_DLV_BADADDR); + } + strcpy(new_attr->ar_data, name); + + new_attr->ar_rel_type = R_MIPS_NONE; + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(die, new_attr); + return new_attr; +} + + +/*----------------------------------------------------------------------------- + Add AT_comp_dir attribute to die +------------------------------------------------------------------------------*/ +Dwarf_P_Attribute +dwarf_add_AT_comp_dir(Dwarf_P_Die ownerdie, + char *current_working_directory, + Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + + if (ownerdie == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, + (Dwarf_P_Attribute) DW_DLV_BADADDR); + } + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(ownerdie->di_dbg,sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, + (Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + /* fill in the information */ + new_attr->ar_attribute = DW_AT_comp_dir; + /* assume that form is string, no debug_str yet */ + new_attr->ar_attribute_form = DW_FORM_string; + new_attr->ar_nbytes = strlen(current_working_directory) + 1; + new_attr->ar_next = NULL; + new_attr->ar_reloc_len = 0; + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(current_working_directory)+1); + if (new_attr->ar_data == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_STRING_ALLOC, + (Dwarf_P_Attribute) DW_DLV_BADADDR); + } + strcpy(new_attr->ar_data, current_working_directory); + + new_attr->ar_rel_type = R_MIPS_NONE; + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + +int +_dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + Dwarf_Unsigned offset, Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + int uwordb_size = dbg->de_offset_size; + + if (die == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, -1); + } + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(dbg,sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, -1); + } + + /* fill in the information */ + new_attr->ar_attribute = DW_AT_MIPS_fde; + new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form;; + new_attr->ar_rel_type = dbg->de_offset_reloc; + new_attr->ar_nbytes = uwordb_size; + new_attr->ar_next = NULL; + new_attr->ar_reloc_len = uwordb_size; + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(dbg, uwordb_size); + if (new_attr->ar_data == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT); + } + { + Dwarf_Unsigned du = offset; + + WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data, + (const void *) &du, sizeof(du), uwordb_size); + } + + _dwarf_pro_add_at_to_die(die, new_attr); + + return 0; +} + +int +_dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + Dwarf_Unsigned offset, Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + int uwordb_size = dbg->de_offset_size; + + if (die == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, -1); + } + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(dbg,sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, -1); + } + + /* fill in the information */ + new_attr->ar_attribute = DW_AT_macro_info; + new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form; + new_attr->ar_rel_type = dbg->de_offset_reloc; + + new_attr->ar_nbytes = uwordb_size; + new_attr->ar_next = NULL; + new_attr->ar_reloc_len = uwordb_size; + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(dbg, uwordb_size); + if (new_attr->ar_data == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT); + } + { + Dwarf_Unsigned du = offset; + + WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data, + (const void *) &du, sizeof(du), uwordb_size); + } + + _dwarf_pro_add_at_to_die(die, new_attr); + + return 0; +} + + +void +_dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr) +{ + if (die->di_last_attr) { + die->di_last_attr->ar_next = attr; + die->di_last_attr = attr; + die->di_n_attr++; + } else { + die->di_n_attr = 1; + die->di_attrs = die->di_last_attr = attr; + } +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_die.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_die.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,68 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + + +/* + This struct holds the abbreviation table, before they are written + on disk. Holds a linked list of abbreviations, each consisting of + a bitmap for attributes and a bitmap for forms +*/ +typedef struct Dwarf_P_Abbrev_s *Dwarf_P_Abbrev; + +struct Dwarf_P_Abbrev_s { + Dwarf_Unsigned abb_idx; /* index of abbreviation */ + Dwarf_Tag abb_tag; /* tag of die */ + Dwarf_Ubyte abb_children; /* if children are present */ + Dwarf_ufixed *abb_attrs; /* holds names of attrs */ + Dwarf_ufixed *abb_forms; /* forms of attributes */ + int abb_n_attr; /* num of attrs = # of forms */ + Dwarf_P_Abbrev abb_next; +}; + +/* used in pro_section.c */ + +int _dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg, Dwarf_P_Die die, + Dwarf_Unsigned offset, Dwarf_Error * error); + +int _dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg, + Dwarf_P_Die first_die, + Dwarf_Error * error); + +int _dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg, + Dwarf_P_Die first_die, + Dwarf_Unsigned offset, + Dwarf_Error * error); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_encode_nm.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_encode_nm.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,123 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include "pro_incl.h" + +#define MORE_BYTES 0x80 +#define DATA_MASK 0x7f +#define DIGIT_WIDTH 7 +#define SIGN_BIT 0x40 + + +/*------------------------------------------------------------- + Encode val as a leb128. This encodes it as an unsigned + number. +---------------------------------------------------------------*/ +/* return DW_DLV_ERROR or DW_DLV_OK. +** space to write leb number is provided by caller, with caller +** passing length. +** number of bytes used returned thru nbytes arg +*/ +int +_dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val, int *nbytes, + char *space, int splen) +{ + char *a; + char *end = space + splen; + + a = space; + do { + unsigned char uc; + + if (a >= end) { + return DW_DLV_ERROR; + } + uc = val & DATA_MASK; + val >>= DIGIT_WIDTH; + if (val != 0) { + uc |= MORE_BYTES; + } + *a = uc; + a++; + } while (val); + *nbytes = a - space; + return DW_DLV_OK; +} + +/* return DW_DLV_ERROR or DW_DLV_OK. +** space to write leb number is provided by caller, with caller +** passing length. +** number of bytes used returned thru nbytes arg +** encodes a signed number. +*/ +int +_dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value, int *nbytes, + char *space, int splen) +{ + char *str; + Dwarf_Signed sign = -(value < 0); + int more = 1; + char *end = space + splen; + + str = space; + + do { + unsigned char byte = value & DATA_MASK; + + value >>= DIGIT_WIDTH; + + if (str >= end) { + return DW_DLV_ERROR; + } + /* + * Remaining chunks would just contain the sign bit, and this chunk + * has already captured at least one sign bit. + */ + if (value == sign && ((byte & SIGN_BIT) == (sign & SIGN_BIT))) { + more = 0; + } else { + byte |= MORE_BYTES; + } + *str = byte; + str++; + } while (more); + *nbytes = str - space; + return DW_DLV_OK; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_encode_nm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_encode_nm.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,48 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +/* Bytes needed to encode a number. + Not a tight bound, just a reasonable bound. +*/ +#define ENCODE_SPACE_NEEDED (2*sizeof(Dwarf_Unsigned)) + + +int _dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val, int *nbytes, + char *space, int splen); + +int _dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value, int *nbytes, + char *space, int splen); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_error.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_error.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,97 @@ +/* + + Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#ifdef HAVE_ELF_H +#include +#endif + +#include +#include +#include +#include +#include "pro_incl.h" + +extern char *_dwarf_errmsgs[]; + +/* + This function performs error handling as described in the + libdwarf consumer document section 3. Dbg is the Dwarf_P_debug + structure being processed. Error is a pointer to the pointer + to the error descriptor that will be returned. Errval is an + error code listed in dwarf_error.h. +*/ +void +_dwarf_p_error(Dwarf_P_Debug dbg, + Dwarf_Error * error, Dwarf_Word errval) +{ + Dwarf_Error errptr; + + /* Allow NULL dbg on entry, since sometimes that can happen and we + want to report the upper-level error, not this one. */ + if ((Dwarf_Sword) errval < 0) + printf("ERROR VALUE: %ld - %s\n", + (long) errval, _dwarf_errmsgs[-errval - 1]); + if (error != NULL) { + errptr = (Dwarf_Error) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_Error_s)); + if (errptr == NULL) { + fprintf(stderr, + "Could not allocate Dwarf_Error structure\n"); + abort(); + } + errptr->er_errval = (Dwarf_Sword) errval; + *error = errptr; + return; + } + + if (dbg != NULL && dbg->de_errhand != NULL) { + errptr = (Dwarf_Error) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_Error_s)); + if (errptr == NULL) { + fprintf(stderr, + "Could not allocate Dwarf_Error structure\n"); + abort(); + } + errptr->er_errval = (Dwarf_Sword) errval; + dbg->de_errhand(errptr, dbg->de_errarg); + return; + } + + abort(); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_error.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_error.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,52 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + + +/* Handle error passing in the name of the Dwarf_P_Debug + User must supply {} around the macro. + Putting the {} here leads to macro uses that don't look like C. + The error argument to dwarf_error is hard coded here as 'error' +*/ +#define DWARF_P_DBG_ERROR(dbg,errval,retval) \ + _dwarf_p_error(dbg,error,errval); return(retval); + +struct Dwarf_Error_s { + Dwarf_Sword er_errval; +}; + +void _dwarf_p_error(Dwarf_P_Debug dbg, Dwarf_Error * error, + Dwarf_Word errval); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_expr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_expr.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,596 @@ +/* + + Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#include "pro_incl.h" +#include "pro_expr.h" + +/* + This function creates a new expression + struct that can be used to build up a + location expression. +*/ +Dwarf_P_Expr +dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + Dwarf_P_Expr ret_expr; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return (NULL); + } + + ret_expr = (Dwarf_P_Expr) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Expr_s)); + if (ret_expr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (NULL); + } + + ret_expr->ex_dbg = dbg; + + return (ret_expr); +} + + +Dwarf_Unsigned +dwarf_add_expr_gen(Dwarf_P_Expr expr, + Dwarf_Small opcode, + Dwarf_Unsigned val1, + Dwarf_Unsigned val2, Dwarf_Error * error) +{ + char encode_buffer[2 * ENCODE_SPACE_NEEDED]; /* 2* since + used to + concatenate + 2 leb's + below */ + char encode_buffer2[ENCODE_SPACE_NEEDED]; + int res; + Dwarf_P_Debug dbg = expr->ex_dbg; + + /* + Give the buffer where the operands are first going to be + assembled the largest alignment. */ + Dwarf_Unsigned operand_buffer[10]; + + /* + Size of the byte stream buffer that needs to be memcpy-ed. */ + int operand_size; + + /* + Points to the byte stream for the first operand, and finally to + the buffer that is memcp-ed into the Dwarf_P_Expr_s struct. */ + Dwarf_Small *operand; + + /* Size of the byte stream for second operand. */ + int operand2_size; + + /* Points to next byte to be written in Dwarf_P_Expr_s struct. */ + Dwarf_Small *next_byte_ptr; + + /* Offset past the last byte written into Dwarf_P_Expr_s. */ + int next_byte_offset; + + /* ***** BEGIN CODE ***** */ + + if (expr == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); + return (DW_DLV_NOCOUNT); + } + + if (expr->ex_dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_NOCOUNT); + } + + operand = NULL; + operand_size = 0; + + switch (opcode) { + case DW_OP_reg0: + case DW_OP_reg1: + case DW_OP_reg2: + case DW_OP_reg3: + case DW_OP_reg4: + case DW_OP_reg5: + case DW_OP_reg6: + case DW_OP_reg7: + case DW_OP_reg8: + case DW_OP_reg9: + case DW_OP_reg10: + case DW_OP_reg11: + case DW_OP_reg12: + case DW_OP_reg13: + case DW_OP_reg14: + case DW_OP_reg15: + case DW_OP_reg16: + case DW_OP_reg17: + case DW_OP_reg18: + case DW_OP_reg19: + case DW_OP_reg20: + case DW_OP_reg21: + case DW_OP_reg22: + case DW_OP_reg23: + case DW_OP_reg24: + case DW_OP_reg25: + case DW_OP_reg26: + case DW_OP_reg27: + case DW_OP_reg28: + case DW_OP_reg29: + case DW_OP_reg30: + case DW_OP_reg31: + break; + + case DW_OP_breg0: + case DW_OP_breg1: + case DW_OP_breg2: + case DW_OP_breg3: + case DW_OP_breg4: + case DW_OP_breg5: + case DW_OP_breg6: + case DW_OP_breg7: + case DW_OP_breg8: + case DW_OP_breg9: + case DW_OP_breg10: + case DW_OP_breg11: + case DW_OP_breg12: + case DW_OP_breg13: + case DW_OP_breg14: + case DW_OP_breg15: + case DW_OP_breg16: + case DW_OP_breg17: + case DW_OP_breg18: + case DW_OP_breg19: + case DW_OP_breg20: + case DW_OP_breg21: + case DW_OP_breg22: + case DW_OP_breg23: + case DW_OP_breg24: + case DW_OP_breg25: + case DW_OP_breg26: + case DW_OP_breg27: + case DW_OP_breg28: + case DW_OP_breg29: + case DW_OP_breg30: + case DW_OP_breg31: + res = _dwarf_pro_encode_signed_leb128_nm(val1, + &operand_size, + encode_buffer, + sizeof(encode_buffer)); + if (res != DW_DLV_OK) { + _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); + return (DW_DLV_NOCOUNT); + } + operand = (Dwarf_Small *) encode_buffer; + break; + + case DW_OP_regx: + res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, + encode_buffer, + sizeof(encode_buffer)); + if (res != DW_DLV_OK) { + _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); + return (DW_DLV_NOCOUNT); + } + operand = (Dwarf_Small *) encode_buffer; + break; + + case DW_OP_lit0: + case DW_OP_lit1: + case DW_OP_lit2: + case DW_OP_lit3: + case DW_OP_lit4: + case DW_OP_lit5: + case DW_OP_lit6: + case DW_OP_lit7: + case DW_OP_lit8: + case DW_OP_lit9: + case DW_OP_lit10: + case DW_OP_lit11: + case DW_OP_lit12: + case DW_OP_lit13: + case DW_OP_lit14: + case DW_OP_lit15: + case DW_OP_lit16: + case DW_OP_lit17: + case DW_OP_lit18: + case DW_OP_lit19: + case DW_OP_lit20: + case DW_OP_lit21: + case DW_OP_lit22: + case DW_OP_lit23: + case DW_OP_lit24: + case DW_OP_lit25: + case DW_OP_lit26: + case DW_OP_lit27: + case DW_OP_lit28: + case DW_OP_lit29: + case DW_OP_lit30: + case DW_OP_lit31: + break; + + case DW_OP_addr: + _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); + return (DW_DLV_NOCOUNT); + + case DW_OP_const1u: + case DW_OP_const1s: + operand = (Dwarf_Small *) & operand_buffer[0]; + WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 1); + operand_size = 1; + break; + + case DW_OP_const2u: + case DW_OP_const2s: + operand = (Dwarf_Small *) & operand_buffer[0]; + WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2); + operand_size = 2; + break; + + case DW_OP_const4u: + case DW_OP_const4s: + operand = (Dwarf_Small *) & operand_buffer[0]; + WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4); + operand_size = 4; + break; + + case DW_OP_const8u: + case DW_OP_const8s: + operand = (Dwarf_Small *) & operand_buffer[0]; + WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 8); + operand_size = 8; + break; + + case DW_OP_constu: + res = _dwarf_pro_encode_leb128_nm(val1, + &operand_size, + encode_buffer, + sizeof(encode_buffer)); + if (res != DW_DLV_OK) { + _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); + return (DW_DLV_NOCOUNT); + } + operand = (Dwarf_Small *) encode_buffer; + break; + + case DW_OP_consts: + res = _dwarf_pro_encode_signed_leb128_nm(val1, + &operand_size, + encode_buffer, + sizeof(encode_buffer)); + if (res != DW_DLV_OK) { + _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); + return (DW_DLV_NOCOUNT); + } + operand = (Dwarf_Small *) encode_buffer; + break; + + case DW_OP_fbreg: + res = _dwarf_pro_encode_signed_leb128_nm(val1, + &operand_size, + encode_buffer, + sizeof(encode_buffer)); + if (res != DW_DLV_OK) { + _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); + return (DW_DLV_NOCOUNT); + } + operand = (Dwarf_Small *) encode_buffer; + break; + + case DW_OP_bregx: + res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, + encode_buffer, + sizeof(encode_buffer)); + if (res != DW_DLV_OK) { + _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); + return (DW_DLV_NOCOUNT); + } + operand = (Dwarf_Small *) encode_buffer; + /* put this one directly into 'operand' at tail of prev value */ + res = _dwarf_pro_encode_signed_leb128_nm(val2, &operand2_size, + ((char *) operand) + + operand_size, + sizeof + (encode_buffer2)); + if (res != DW_DLV_OK) { + _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); + return (DW_DLV_NOCOUNT); + } + operand_size += operand2_size; + + case DW_OP_dup: + case DW_OP_drop: + break; + + case DW_OP_pick: + operand = (Dwarf_Small *) & operand_buffer[0]; + WRITE_UNALIGNED(dbg, operand, (const void *) &val1, + sizeof(val1), 1); + operand_size = 1; + break; + + case DW_OP_over: + case DW_OP_swap: + case DW_OP_rot: + case DW_OP_deref: + case DW_OP_xderef: + break; + + case DW_OP_deref_size: + case DW_OP_xderef_size: + operand = (Dwarf_Small *) & operand_buffer[0]; + WRITE_UNALIGNED(dbg, operand, (const void *) &val1, + sizeof(val1), 1); + operand_size = 1; + break; + + case DW_OP_abs: + case DW_OP_and: + case DW_OP_div: + case DW_OP_minus: + case DW_OP_mod: + case DW_OP_mul: + case DW_OP_neg: + case DW_OP_not: + case DW_OP_or: + case DW_OP_plus: + break; + + case DW_OP_plus_uconst: + res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, + encode_buffer, + sizeof(encode_buffer)); + if (res != DW_DLV_OK) { + _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); + return (DW_DLV_NOCOUNT); + } + operand = (Dwarf_Small *) encode_buffer; + break; + + case DW_OP_shl: + case DW_OP_shr: + case DW_OP_shra: + case DW_OP_xor: + break; + + case DW_OP_le: + case DW_OP_ge: + case DW_OP_eq: + case DW_OP_lt: + case DW_OP_gt: + case DW_OP_ne: + break; + + case DW_OP_skip: + case DW_OP_bra: + /* FIX: unhandled! OP_bra, OP_skip! */ + _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); + return (DW_DLV_NOCOUNT); + + case DW_OP_piece: + res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, + encode_buffer, + sizeof(encode_buffer)); + if (res != DW_DLV_OK) { + _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); + return (DW_DLV_NOCOUNT); + } + operand = (Dwarf_Small *) encode_buffer; + break; + + case DW_OP_nop: + break; + case DW_OP_push_object_address: /* DWARF3 */ + break; + case DW_OP_call2: /* DWARF3 */ + operand = (Dwarf_Small *) & operand_buffer[0]; + WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2); + operand_size = 2; + break; + + case DW_OP_call4: /* DWARF3 */ + operand = (Dwarf_Small *) & operand_buffer[0]; + WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4); + operand_size = 4; + break; + + case DW_OP_call_ref: /* DWARF3 */ + operand = (Dwarf_Small *) & operand_buffer[0]; + WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), + dbg->de_offset_size); + operand_size = dbg->de_offset_size; + break; + case DW_OP_form_tls_address: /* DWARF3f */ + break; + case DW_OP_call_frame_cfa: /* DWARF3f */ + break; + case DW_OP_bit_piece: /* DWARF3f */ + res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, + encode_buffer, + sizeof(encode_buffer)); + if (res != DW_DLV_OK) { + _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); + return (DW_DLV_NOCOUNT); + } + operand = (Dwarf_Small *) encode_buffer; + /* put this one directly into 'operand' at tail of prev value */ + res = _dwarf_pro_encode_leb128_nm(val2, &operand2_size, + ((char *) operand) + + operand_size, + sizeof(encode_buffer2)); + if (res != DW_DLV_OK) { + _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); + return (DW_DLV_NOCOUNT); + } + operand_size += operand2_size; + + + default: + _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); + return (DW_DLV_NOCOUNT); + } + + next_byte_offset = expr->ex_next_byte_offset + operand_size + 1; + + if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) { + _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); + return (DW_DLV_NOCOUNT); + } + + next_byte_ptr = + &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset; + + *next_byte_ptr = opcode; + next_byte_ptr++; + memcpy(next_byte_ptr, operand, operand_size); + + expr->ex_next_byte_offset = next_byte_offset; + return (next_byte_offset); +} + +Dwarf_Unsigned +dwarf_add_expr_addr_b(Dwarf_P_Expr expr, + Dwarf_Unsigned addr, + Dwarf_Unsigned sym_index, Dwarf_Error * error) +{ + Dwarf_P_Debug dbg; + Dwarf_Small *next_byte_ptr; + Dwarf_Unsigned next_byte_offset; + int upointer_size; + + if (expr == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); + return (DW_DLV_NOCOUNT); + } + + dbg = expr->ex_dbg; + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_NOCOUNT); + } + + upointer_size = dbg->de_pointer_size; + next_byte_offset = expr->ex_next_byte_offset + upointer_size + 1; + if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) { + _dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD); + return (DW_DLV_NOCOUNT); + } + + next_byte_ptr = + &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset; + + *next_byte_ptr = DW_OP_addr; + next_byte_ptr++; + WRITE_UNALIGNED(dbg, next_byte_ptr, (const void *) &addr, + sizeof(addr), upointer_size); + + if (expr->ex_reloc_offset != 0) { + _dwarf_p_error(dbg, error, DW_DLE_MULTIPLE_RELOC_IN_EXPR); + return (DW_DLV_NOCOUNT); + } + + expr->ex_reloc_sym_index = sym_index; + expr->ex_reloc_offset = expr->ex_next_byte_offset + 1; + + expr->ex_next_byte_offset = next_byte_offset; + return (next_byte_offset); +} + +Dwarf_Unsigned +dwarf_add_expr_addr(Dwarf_P_Expr expr, + Dwarf_Unsigned addr, + Dwarf_Signed sym_index, Dwarf_Error * error) +{ + return + dwarf_add_expr_addr_b(expr, addr, (Dwarf_Unsigned) sym_index, + error); +} + + +Dwarf_Unsigned +dwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error * error) +{ + if (expr == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); + return (DW_DLV_NOCOUNT); + } + + if (expr->ex_dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_NOCOUNT); + } + + return (expr->ex_next_byte_offset); +} + +void +dwarf_expr_reset(Dwarf_P_Expr expr, Dwarf_Error * error) +{ + if (expr == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); + return; + } + expr->ex_next_byte_offset=0; +} + + +Dwarf_Addr +dwarf_expr_into_block(Dwarf_P_Expr expr, + Dwarf_Unsigned * length, Dwarf_Error * error) +{ + if (expr == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); + return (DW_DLV_BADADDR); + } + + if (expr->ex_dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_BADADDR); + } + + if (length != NULL) + *length = expr->ex_next_byte_offset; + /* The following cast from pointer to integer is ok as long as + Dwarf_Addr is at least as large as a pointer. Which is a + requirement of libdwarf so must be satisfied (some compilers + emit a warning about the following line). */ + return ((Dwarf_Addr) & (expr->ex_byte_stream[0])); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_expr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_expr.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,45 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + +#define MAXIMUM_LOC_EXPR_LENGTH 20 + +struct Dwarf_P_Expr_s { + Dwarf_Small ex_byte_stream[MAXIMUM_LOC_EXPR_LENGTH]; + Dwarf_P_Debug ex_dbg; + Dwarf_Unsigned ex_next_byte_offset; + Dwarf_Unsigned ex_reloc_sym_index; + Dwarf_Unsigned ex_reloc_offset; +}; diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_finish.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_finish.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,57 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include "pro_incl.h" + +/*--------------------------------------------------------------- + This routine deallocates all memory, and does some + finishing up +-----------------------------------------------------------------*/ + /*ARGSUSED*/ Dwarf_Unsigned +dwarf_producer_finish(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_NOCOUNT); + } + + /* this frees all blocks, then frees dbg. */ + _dwarf_p_dealloc_all(dbg); + return 0; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_forms.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_forms.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1164 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved. + Portions Copyright 2007 David Anderson. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#include +#include "pro_incl.h" +#include "pro_expr.h" + +#ifndef R_MIPS_NONE +#define R_MIPS_NONE 0 +#endif + + + /* Indicates no relocation needed. */ +#define NO_ELF_SYM_INDEX 0 + + +/* adds an attribute to a die */ +extern void _dwarf_pro_add_at_to_die(Dwarf_P_Die die, + Dwarf_P_Attribute attr); + +/* + This function adds an attribute whose value is + a target address to the given die. The attribute + is given the name provided by attr. The address + is given in pc_value. +*/ + +static Dwarf_P_Attribute +local_add_AT_address(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Signed form, + Dwarf_Unsigned pc_value, + Dwarf_Unsigned sym_index, + Dwarf_Error * error); + +/* old interface */ +Dwarf_P_Attribute +dwarf_add_AT_targ_address(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Unsigned pc_value, + Dwarf_Signed sym_index, Dwarf_Error * error) +{ + return + dwarf_add_AT_targ_address_b(dbg, + ownerdie, + attr, + pc_value, + (Dwarf_Unsigned) sym_index, error); +} + +/* New interface, replacing dwarf_add_AT_targ_address. + Essentially just makes sym_index a Dwarf_Unsigned + so for symbolic relocations it can be a full address. +*/ +Dwarf_P_Attribute +dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Unsigned pc_value, + Dwarf_Unsigned sym_index, + Dwarf_Error * error) +{ + switch (attr) { + case DW_AT_low_pc: + case DW_AT_high_pc: + + /* added to support location lists */ + /* no way to check that this is a loclist-style address though */ + case DW_AT_location: + case DW_AT_string_length: + case DW_AT_return_addr: + case DW_AT_frame_base: + case DW_AT_segment: + case DW_AT_static_link: + case DW_AT_use_location: + case DW_AT_vtable_elem_location: + + break; + + default: + if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { + _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + break; + } + + return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_addr, + pc_value, sym_index, error); +} + +Dwarf_P_Attribute +dwarf_add_AT_ref_address(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Unsigned pc_value, + Dwarf_Unsigned sym_index, + Dwarf_Error * error) +{ + switch (attr) { + case DW_AT_type: + case DW_AT_import: + break; + + default: + if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { + _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + break; + } + + return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_ref_addr, + pc_value, sym_index, error); +} + + +/* Make sure attribute types are checked before entering here. */ +static Dwarf_P_Attribute +local_add_AT_address(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Signed form, + Dwarf_Unsigned pc_value, + Dwarf_Unsigned sym_index, + Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + int upointer_size = dbg->de_pointer_size; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + if (ownerdie == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + /* attribute types have already been checked */ + /* switch (attr) { ... } */ + + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + new_attr->ar_attribute = attr; + new_attr->ar_attribute_form = form; + new_attr->ar_nbytes = upointer_size; + new_attr->ar_rel_symidx = sym_index; + new_attr->ar_reloc_len = upointer_size; + new_attr->ar_next = 0; + if (sym_index != NO_ELF_SYM_INDEX) + new_attr->ar_rel_type = dbg->de_ptr_reloc; + else + new_attr->ar_rel_type = R_MIPS_NONE; + + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(dbg, upointer_size); + if (new_attr->ar_data == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + WRITE_UNALIGNED(dbg, new_attr->ar_data, + (const void *) &pc_value, + sizeof(pc_value), upointer_size); + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + +/* + * Functions to compress and uncompress data from normal + * arrays of integral types into arrays of LEB128 numbers. + * Extend these functions as needed to handle wider input + * variety. Return values should be freed with _dwarf_p_dealloc + * after they aren't needed any more. + */ + +/* return value points to an array of LEB number */ + +void * +dwarf_compress_integer_block( + Dwarf_P_Debug dbg, + Dwarf_Bool unit_is_signed, + Dwarf_Small unit_length_in_bits, + void* input_block, + Dwarf_Unsigned input_length_in_units, + Dwarf_Unsigned* output_length_in_bytes_ptr, + Dwarf_Error* error +) +{ + Dwarf_Unsigned output_length_in_bytes; + char * output_block; + char encode_buffer[ENCODE_SPACE_NEEDED]; + int unit_length; + int i; + char * ptr; + int remain; + int result; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return((void *)DW_DLV_BADADDR); + } + + if (unit_is_signed == false || + unit_length_in_bits != 32 || + input_block == NULL || + input_length_in_units == 0 || + output_length_in_bytes_ptr == NULL) { + + _dwarf_p_error(NULL, error, DW_DLE_BADBITC); + return ((void *) DW_DLV_BADADDR); + } + + /* At this point we assume the format is: signed 32 bit */ + + /* first compress everything to find the total size. */ + + output_length_in_bytes = 0; + for (i=0; ide_ar_data_attribute_form is data4 or data8 + and dwarf4 changes the definition for such on DW_AT_high_pc. + DWARF 3: the FORM here has no defined meaning for dwarf3. + DWARF 4: the FORM here means that for DW_AT_high_pc the value + is not a high address but is instead an offset + from a (separate) DW_AT_low_pc. + The intent for DWARF4 is that this is not a relocated + address at all. Instead a simple offset. + But this should NOT be called for a simple non-relocated offset. + So do not call this with an attr of DW_AT_high_pc. + Use dwarf_add_AT_unsigned_const() (for example) instead of + dwarf_add_AT_dataref when the value is a simple offset . +*/ +Dwarf_P_Attribute +dwarf_add_AT_dataref( + Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Unsigned pc_value, + Dwarf_Unsigned sym_index, + Dwarf_Error * error) +{ + /* TODO: Add checking here */ + return local_add_AT_address(dbg, ownerdie, attr, + dbg->de_ar_data_attribute_form, + pc_value, + sym_index, + error); +} + + + +Dwarf_P_Attribute +dwarf_add_AT_block( + Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Small *block_data, + Dwarf_Unsigned block_size, + Dwarf_Error *error +) +{ + Dwarf_P_Attribute new_attr; + int result; + char encode_buffer[ENCODE_SPACE_NEEDED]; + int len_size; + char * attrdata; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return((Dwarf_P_Attribute)DW_DLV_BADADDR); + } + + if (ownerdie == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return((Dwarf_P_Attribute)DW_DLV_BADADDR); + } + + /* I don't mess with block1, block2, block4, not worth the effort */ + + /* So, encode the length into LEB128 */ + result = _dwarf_pro_encode_leb128_nm(block_size, &len_size, + encode_buffer,sizeof(encode_buffer)); + if (result != DW_DLV_OK) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return((Dwarf_P_Attribute)DW_DLV_BADADDR); + } + + /* Allocate the new attribute */ + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return((Dwarf_P_Attribute)DW_DLV_BADADDR); + } + + /* Fill in the attribute */ + new_attr->ar_attribute = attr; + new_attr->ar_attribute_form = DW_FORM_block; + new_attr->ar_nbytes = len_size + block_size; + new_attr->ar_next = 0; + + new_attr->ar_data = attrdata = (char *) + _dwarf_p_get_alloc(dbg, len_size + block_size); + if (new_attr->ar_data == NULL) { + /* free the block we got earlier */ + _dwarf_p_dealloc(dbg, (unsigned char *) new_attr); + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return((Dwarf_P_Attribute)DW_DLV_BADADDR); + } + + /* write length and data to attribute data buffer */ + memcpy(attrdata, encode_buffer, len_size); + attrdata += len_size; + memcpy(attrdata, block_data, block_size); + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + + return new_attr; +} + + +/* + This function adds attributes whose value + is an unsigned constant. It determines the + size of the value field from the value of + the constant. +*/ +Dwarf_P_Attribute +dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Unsigned value, Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + Dwarf_Half attr_form; + Dwarf_Small size; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + if (ownerdie == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + switch (attr) { + case DW_AT_ordering: + case DW_AT_byte_size: + case DW_AT_bit_offset: + case DW_AT_bit_size: + case DW_AT_inline: + case DW_AT_language: + case DW_AT_visibility: + case DW_AT_virtuality: + case DW_AT_accessibility: + case DW_AT_address_class: + case DW_AT_calling_convention: + case DW_AT_encoding: + case DW_AT_identifier_case: + case DW_AT_MIPS_loop_unroll_factor: + case DW_AT_MIPS_software_pipeline_depth: + break; + + case DW_AT_decl_column: + case DW_AT_decl_file: + case DW_AT_decl_line: + case DW_AT_const_value: + case DW_AT_start_scope: + case DW_AT_stride_size: + case DW_AT_count: + case DW_AT_associated: + case DW_AT_allocated: + case DW_AT_upper_bound: + case DW_AT_lower_bound: + break; + + default: { + if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { + _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + break; + } + } + + /* + Compute the number of bytes needed to hold constant. */ + if (value <= UCHAR_MAX) { + attr_form = DW_FORM_data1; + size = 1; + } else if (value <= USHRT_MAX) { + attr_form = DW_FORM_data2; + size = 2; + } else if (value <= UINT_MAX) { + attr_form = DW_FORM_data4; + size = 4; + } else { + attr_form = DW_FORM_data8; + size = 8; + } + + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + new_attr->ar_attribute = attr; + new_attr->ar_attribute_form = attr_form; + new_attr->ar_rel_type = R_MIPS_NONE; + new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */ + new_attr->ar_nbytes = size; + new_attr->ar_next = 0; + + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(dbg, size); + if (new_attr->ar_data == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + WRITE_UNALIGNED(dbg, new_attr->ar_data, + (const void *) &value, sizeof(value), size); + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +/* + This function adds attributes whose value + is an signed constant. It determines the + size of the value field from the value of + the constant. +*/ +Dwarf_P_Attribute +dwarf_add_AT_signed_const(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Signed value, Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + Dwarf_Half attr_form; + Dwarf_Small size; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + if (ownerdie == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + switch (attr) { + case DW_AT_upper_bound: + case DW_AT_lower_bound: + case DW_AT_const_value: + break; + + default:{ + if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { + _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + } + break; + } + + /* + Compute the number of bytes needed to hold constant. */ + if (value >= SCHAR_MIN && value <= SCHAR_MAX) { + attr_form = DW_FORM_data1; + size = 1; + } else if (value >= SHRT_MIN && value <= SHRT_MAX) { + attr_form = DW_FORM_data2; + size = 2; + } else if (value >= INT_MIN && value <= INT_MAX) { + attr_form = DW_FORM_data4; + size = 4; + } else { + attr_form = DW_FORM_data8; + size = 8; + } + + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + new_attr->ar_attribute = attr; + new_attr->ar_attribute_form = attr_form; + new_attr->ar_rel_type = R_MIPS_NONE; + new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */ + new_attr->ar_nbytes = size; + new_attr->ar_next = 0; + + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(dbg, size); + if (new_attr->ar_data == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + WRITE_UNALIGNED(dbg, new_attr->ar_data, + (const void *) &value, sizeof(value), size); + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +/* + This function adds attributes whose value + is a location expression. +*/ +Dwarf_P_Attribute +dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_P_Expr loc_expr, Dwarf_Error * error) +{ + char encode_buffer[ENCODE_SPACE_NEEDED]; + int res; + Dwarf_P_Attribute new_attr; + Dwarf_Half attr_form; + char *len_str = 0; + int len_size; + int block_size; + char *block_dest_ptr; + int do_len_as_int = 0; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + if (ownerdie == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + if (loc_expr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_EXPR_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + if (loc_expr->ex_dbg != dbg) { + _dwarf_p_error(dbg, error, DW_DLE_LOC_EXPR_BAD); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + block_size = loc_expr->ex_next_byte_offset; + + switch (attr) { + case DW_AT_location: + case DW_AT_string_length: + case DW_AT_const_value: + case DW_AT_use_location: + case DW_AT_return_addr: + case DW_AT_data_member_location: + case DW_AT_frame_base: + case DW_AT_static_link: + case DW_AT_vtable_elem_location: + case DW_AT_lower_bound: + case DW_AT_upper_bound: + case DW_AT_count: + case DW_AT_associated: + case DW_AT_allocated: + break; + + default: + if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { + _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + break; + } + + /* + Compute the number of bytes needed to hold constant. */ + if (block_size <= UCHAR_MAX) { + attr_form = DW_FORM_block1; + len_size = 1; + do_len_as_int = 1; + } else if (block_size <= USHRT_MAX) { + attr_form = DW_FORM_block2; + len_size = 2; + do_len_as_int = 1; + } else if (block_size <= UINT_MAX) { + attr_form = DW_FORM_block4; + len_size = 4; + do_len_as_int = 1; + } else { + attr_form = DW_FORM_block; + res = _dwarf_pro_encode_leb128_nm(block_size, &len_size, + encode_buffer, + sizeof(encode_buffer)); + if (res != DW_DLV_OK) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + len_str = (char *) encode_buffer; + } + + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + new_attr->ar_attribute = attr; + new_attr->ar_attribute_form = attr_form; + new_attr->ar_reloc_len = dbg->de_pointer_size; + if (loc_expr->ex_reloc_sym_index != NO_ELF_SYM_INDEX) { + new_attr->ar_rel_type = dbg->de_ptr_reloc; + } else { + new_attr->ar_rel_type = R_MIPS_NONE; + } + new_attr->ar_rel_symidx = loc_expr->ex_reloc_sym_index; + new_attr->ar_rel_offset = + (Dwarf_Word) loc_expr->ex_reloc_offset + len_size; + + new_attr->ar_nbytes = block_size + len_size; + + new_attr->ar_next = 0; + new_attr->ar_data = block_dest_ptr = + (char *) _dwarf_p_get_alloc(dbg, block_size + len_size); + if (new_attr->ar_data == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + if (do_len_as_int) { + WRITE_UNALIGNED(dbg, block_dest_ptr, (const void *) &block_size, + sizeof(block_size), len_size); + } else { + /* Is uleb number form, DW_FORM_block. See above. */ + memcpy(block_dest_ptr, len_str, len_size); + } + block_dest_ptr += len_size; + memcpy(block_dest_ptr, &(loc_expr->ex_byte_stream[0]), block_size); + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +/* + This function adds attributes of reference class. + The references here are local CU references, + not DW_FORM_ref_addr. + The offset field is 4 bytes for 32-bit objects, + and 8-bytes for 64-bit objects. Otherdie is the + that is referenced by ownerdie. + + For reference attributes, the ar_data and ar_nbytes + are not needed. Instead, the ar_ref_die points to + the other die, and its di_offset value is used as + the reference value. +*/ +Dwarf_P_Attribute +dwarf_add_AT_reference(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_P_Die otherdie, Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + if (ownerdie == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + if (otherdie == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + switch (attr) { + case DW_AT_specification: + case DW_AT_discr: + case DW_AT_common_reference: + case DW_AT_import: + case DW_AT_containing_type: + case DW_AT_default_value: + case DW_AT_abstract_origin: + case DW_AT_friend: + case DW_AT_priority: + case DW_AT_type: + case DW_AT_lower_bound: + case DW_AT_upper_bound: + case DW_AT_count: + case DW_AT_associated: + case DW_AT_allocated: + case DW_AT_sibling: + case DW_AT_namelist_item: + break; + + default: + if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { + _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + break; + } + + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + new_attr->ar_attribute = attr; + new_attr->ar_attribute_form = dbg->de_ar_ref_attr_form; + new_attr->ar_nbytes = dbg->de_offset_size; + new_attr->ar_reloc_len = dbg->de_offset_size; + new_attr->ar_ref_die = otherdie; + new_attr->ar_rel_type = R_MIPS_NONE; + new_attr->ar_next = 0; + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +/* + This function adds attributes of the flag class. +*/ +Dwarf_P_Attribute +dwarf_add_AT_flag(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Small flag, Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + if (ownerdie == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + +#if 0 + switch (attr) { + case DW_AT_is_optional: + case DW_AT_artificial: + case DW_AT_declaration: + case DW_AT_external: + case DW_AT_prototyped: + case DW_AT_variable_parameter: + break; + + default: + if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { + _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + break; + } +#endif + + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + new_attr->ar_attribute = attr; + new_attr->ar_attribute_form = DW_FORM_flag; + new_attr->ar_nbytes = 1; + new_attr->ar_reloc_len = 0; /* not used */ + new_attr->ar_rel_type = R_MIPS_NONE; + new_attr->ar_next = 0; + + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(dbg, 1); + if (new_attr->ar_data == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + memcpy(new_attr->ar_data, &flag, 1); + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +/* + This function adds values of attributes + belonging to the string class. +*/ +Dwarf_P_Attribute +dwarf_add_AT_string(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, char *string, Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + if (ownerdie == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + switch (attr) { + case DW_AT_name: + case DW_AT_comp_dir: + case DW_AT_const_value: + case DW_AT_producer: + break; + + default: + if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { + _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + break; + } + + new_attr->ar_attribute = attr; + new_attr->ar_attribute_form = DW_FORM_string; + new_attr->ar_nbytes = strlen(string) + 1; + new_attr->ar_next = 0; + + new_attr->ar_data = + (char *) _dwarf_p_get_alloc(dbg, strlen(string)+1); + if (new_attr->ar_data == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + strcpy(new_attr->ar_data, string); + new_attr->ar_rel_type = R_MIPS_NONE; + new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +Dwarf_P_Attribute +dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie, + char *string_value, Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + + if (ownerdie == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + new_attr->ar_attribute = DW_AT_const_value; + new_attr->ar_attribute_form = DW_FORM_string; + new_attr->ar_nbytes = strlen(string_value) + 1; + new_attr->ar_next = 0; + + new_attr->ar_data = + (char *) _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(string_value)+1); + if (new_attr->ar_data == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + strcpy(new_attr->ar_data, string_value); + new_attr->ar_rel_type = R_MIPS_NONE; + new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +Dwarf_P_Attribute +dwarf_add_AT_producer(Dwarf_P_Die ownerdie, + char *producer_string, Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + + if (ownerdie == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + new_attr->ar_attribute = DW_AT_producer; + new_attr->ar_attribute_form = DW_FORM_string; + new_attr->ar_nbytes = strlen(producer_string) + 1; + new_attr->ar_next = 0; + + new_attr->ar_data = + (char *) _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(producer_string)+1); + if (new_attr->ar_data == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + strcpy(new_attr->ar_data, producer_string); + new_attr->ar_rel_type = R_MIPS_NONE; + new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +Dwarf_P_Attribute +dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie, + Dwarf_Signed signed_value, + Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + int leb_size; + char encode_buffer[ENCODE_SPACE_NEEDED]; + int res; + + if (ownerdie == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + new_attr->ar_attribute = DW_AT_const_value; + new_attr->ar_attribute_form = DW_FORM_sdata; + new_attr->ar_rel_type = R_MIPS_NONE; + new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ + new_attr->ar_next = 0; + + res = _dwarf_pro_encode_signed_leb128_nm(signed_value, &leb_size, + encode_buffer, + sizeof(encode_buffer)); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(ownerdie->di_dbg, leb_size); + if (new_attr->ar_data == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + memcpy(new_attr->ar_data, encode_buffer, leb_size); + new_attr->ar_nbytes = leb_size; + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +Dwarf_P_Attribute +dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie, + Dwarf_Unsigned unsigned_value, + Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + int leb_size; + char encode_buffer[ENCODE_SPACE_NEEDED]; + int res; + + if (ownerdie == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + new_attr->ar_attribute = DW_AT_const_value; + new_attr->ar_attribute_form = DW_FORM_udata; + new_attr->ar_rel_type = R_MIPS_NONE; + new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ + new_attr->ar_next = 0; + + res = _dwarf_pro_encode_leb128_nm(unsigned_value, &leb_size, + encode_buffer, + sizeof(encode_buffer)); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(ownerdie->di_dbg, leb_size); + if (new_attr->ar_data == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + memcpy(new_attr->ar_data, encode_buffer, leb_size); + new_attr->ar_nbytes = leb_size; + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_frame.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_frame.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,560 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#include +#include "pro_incl.h" +#include "pro_frame.h" + +static void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, + Dwarf_P_Frame_Pgm inst); + +/*------------------------------------------------------------------------- + This functions adds a cie struct to the debug pointer. Its in the + form of a linked list. + augmenter: string reps augmentation (implementation defined) + code_align: alignment of code + data_align: alignment of data + init_bytes: byts having initial instructions + init_n_bytes: number of bytes of initial instructions +--------------------------------------------------------------------------*/ +Dwarf_Unsigned +dwarf_add_frame_cie(Dwarf_P_Debug dbg, + char *augmenter, + Dwarf_Small code_align, + Dwarf_Small data_align, + Dwarf_Small return_reg, + Dwarf_Ptr init_bytes, + Dwarf_Unsigned init_n_bytes, Dwarf_Error * error) +{ + Dwarf_P_Cie curcie; + + if (dbg->de_frame_cies == NULL) { + dbg->de_frame_cies = (Dwarf_P_Cie) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s)); + if (dbg->de_frame_cies == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT); + } + curcie = dbg->de_frame_cies; + dbg->de_n_cie = 1; + dbg->de_last_cie = curcie; + } else { + curcie = dbg->de_last_cie; + curcie->cie_next = (Dwarf_P_Cie) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s)); + if (curcie->cie_next == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT); + } + curcie = curcie->cie_next; + dbg->de_n_cie++; + dbg->de_last_cie = curcie; + } + curcie->cie_version = DW_CIE_VERSION; + curcie->cie_aug = augmenter; + curcie->cie_code_align = code_align; + curcie->cie_data_align = data_align; + curcie->cie_ret_reg = return_reg; + curcie->cie_inst = (char *) init_bytes; + curcie->cie_inst_bytes = (long) init_n_bytes; + curcie->cie_next = NULL; + return dbg->de_n_cie; +} + + +/*------------------------------------------------------------------------- + This functions adds a fde struct to the debug pointer. Its in the + form of a linked list. + die: subprogram/function die corresponding to this fde + cie: cie referred to by this fde, obtained from call to + add_frame_cie() routine. + virt_addr: beginning address + code_len: length of code reps by the fde +--------------------------------------------------------------------------*/ + /*ARGSUSED*/ /* pretend all args used */ + Dwarf_Unsigned +dwarf_add_frame_fde(Dwarf_P_Debug dbg, + Dwarf_P_Fde fde, + Dwarf_P_Die die, + Dwarf_Unsigned cie, + Dwarf_Unsigned virt_addr, + Dwarf_Unsigned code_len, + Dwarf_Unsigned symidx, Dwarf_Error * error) +{ + return dwarf_add_frame_fde_b(dbg, fde, die, cie, virt_addr, + code_len, symidx, 0, 0, error); +} + +/*ARGSUSED10*/ +Dwarf_Unsigned +dwarf_add_frame_fde_b(Dwarf_P_Debug dbg, + Dwarf_P_Fde fde, + Dwarf_P_Die die, + Dwarf_Unsigned cie, + Dwarf_Unsigned virt_addr, + Dwarf_Unsigned code_len, + Dwarf_Unsigned symidx, + Dwarf_Unsigned symidx_of_end, + Dwarf_Addr offset_from_end_sym, + Dwarf_Error * error) +{ + Dwarf_P_Fde curfde; + + fde->fde_die = die; + fde->fde_cie = (long) cie; + fde->fde_initloc = virt_addr; + fde->fde_r_symidx = symidx; + fde->fde_addr_range = code_len; + fde->fde_offset_into_exception_tables = DW_DLX_NO_EH_OFFSET; + fde->fde_exception_table_symbol = 0; + fde->fde_end_symbol_offset = offset_from_end_sym; + fde->fde_end_symbol = symidx_of_end; + fde->fde_dbg = dbg; + + curfde = dbg->de_last_fde; + if (curfde == NULL) { + dbg->de_frame_fdes = fde; + dbg->de_last_fde = fde; + dbg->de_n_fde = 1; + } else { + curfde->fde_next = fde; + dbg->de_last_fde = fde; + dbg->de_n_fde++; + } + return dbg->de_n_fde; +} + +/*------------------------------------------------------------------------- + This functions adds information to an fde. The fde is + linked into the linked list of fde's maintained in the Dwarf_P_Debug + structure. + dbg: The debug descriptor. + fde: The fde to be added. + die: subprogram/function die corresponding to this fde + cie: cie referred to by this fde, obtained from call to + add_frame_cie() routine. + virt_addr: beginning address + code_len: length of code reps by the fde + symidx: The symbol id of the symbol wrt to which relocation needs + to be performed for 'virt_addr'. + offset_into_exception_tables: The start of exception tables for + this function (indicated as an offset into the exception + tables). A value of -1 indicates that there is no exception + table entries associated with this function. + exception_table_symbol: The symbol id of the section for exception + tables wrt to which the offset_into_exception_tables will + be relocated. +--------------------------------------------------------------------------*/ +Dwarf_Unsigned +dwarf_add_frame_info(Dwarf_P_Debug dbg, + Dwarf_P_Fde fde, + Dwarf_P_Die die, + Dwarf_Unsigned cie, + Dwarf_Unsigned virt_addr, + Dwarf_Unsigned code_len, + Dwarf_Unsigned symidx, + Dwarf_Signed offset_into_exception_tables, + Dwarf_Unsigned exception_table_symbol, + Dwarf_Error * error) +{ + + return dwarf_add_frame_info_b(dbg, fde, die, cie, virt_addr, + code_len, symidx, + /* end_symbol */ 0, + /* offset_from_end */ 0, + offset_into_exception_tables, + exception_table_symbol, error); + +} + + /*ARGSUSED*/ /* pretend all args used */ + Dwarf_Unsigned +dwarf_add_frame_info_b(Dwarf_P_Debug dbg, + Dwarf_P_Fde fde, + Dwarf_P_Die die, + Dwarf_Unsigned cie, + Dwarf_Unsigned virt_addr, + Dwarf_Unsigned code_len, + Dwarf_Unsigned symidx, + Dwarf_Unsigned end_symidx, + Dwarf_Unsigned offset_from_end_symbol, + Dwarf_Signed offset_into_exception_tables, + Dwarf_Unsigned exception_table_symbol, + Dwarf_Error * error) +{ + Dwarf_P_Fde curfde; + + fde->fde_die = die; + fde->fde_cie = (long) cie; + fde->fde_initloc = virt_addr; + fde->fde_r_symidx = symidx; + fde->fde_addr_range = code_len; + fde->fde_offset_into_exception_tables = + offset_into_exception_tables; + fde->fde_exception_table_symbol = exception_table_symbol; + fde->fde_end_symbol_offset = offset_from_end_symbol; + fde->fde_end_symbol = end_symidx; + fde->fde_dbg = dbg; + + curfde = dbg->de_last_fde; + if (curfde == NULL) { + dbg->de_frame_fdes = fde; + dbg->de_last_fde = fde; + dbg->de_n_fde = 1; + } else { + curfde->fde_next = fde; + dbg->de_last_fde = fde; + dbg->de_n_fde++; + } + return dbg->de_n_fde; +} + + +/*------------------------------------------------------------------- + Create a new fde +---------------------------------------------------------------------*/ +Dwarf_P_Fde +dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + Dwarf_P_Fde fde; + + fde = (Dwarf_P_Fde) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Fde_s)); + if (fde == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_FDE_ALLOC, + (Dwarf_P_Fde) DW_DLV_BADADDR); + } + fde->fde_next = NULL; + fde->fde_inst = NULL; + fde->fde_n_inst = 0; + fde->fde_n_bytes = 0; + fde->fde_last_inst = NULL; + fde->fde_uwordb_size = dbg->de_offset_size; + return fde; +} + +/*------------------------------------------------------------------------ + Add cfe_offset instruction to fde +-------------------------------------------------------------------------*/ +Dwarf_P_Fde +dwarf_fde_cfa_offset(Dwarf_P_Fde fde, + Dwarf_Unsigned reg, + Dwarf_Signed offset, Dwarf_Error * error) +{ + Dwarf_Ubyte opc, regno; + char *ptr; + Dwarf_P_Frame_Pgm curinst; + int nbytes; + int res; + char buff1[ENCODE_SPACE_NEEDED]; + Dwarf_P_Debug dbg = fde->fde_dbg; + + curinst = (Dwarf_P_Frame_Pgm) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s)); + if (curinst == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_FPGM_ALLOC, + (Dwarf_P_Fde) DW_DLV_BADADDR); + } + opc = DW_CFA_offset; + regno = reg; + if (regno & 0xc0) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_REGNO_OVFL, + (Dwarf_P_Fde) DW_DLV_BADADDR); + } + opc = opc | regno; /* lower 6 bits are register number */ + curinst->dfp_opcode = opc; + res = _dwarf_pro_encode_leb128_nm(offset, &nbytes, + buff1, sizeof(buff1)); + if (res != DW_DLV_OK) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); + if (ptr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + memcpy(ptr, buff1, nbytes); + + curinst->dfp_args = ptr; + curinst->dfp_nbytes = nbytes; + curinst->dfp_next = NULL; + + _dwarf_pro_add_to_fde(fde, curinst); + return fde; +} + +/* + Generic routine to add opcode to fde instructions. val1 and + val2 are parameters whose interpretation depends on the 'op'. + + This does not work properly for DW_DLC_SYMBOLIC_RELOCATIONS + for DW_CFA_set_loc or DW_DVA_advance_loc* 'op', as + these ops normally are addresses or (DW_CFA_set_loc) + or code lengths (DW_DVA_advance_loc*) and such must be + represented with relocations and symbol indices for + DW_DLC_SYMBOLIC_RELOCATIONS. + + This does not treat all DW_CFA instructions and + currently excludes DWARF3 additions. + +*/ +Dwarf_P_Fde +dwarf_add_fde_inst(Dwarf_P_Fde fde, + Dwarf_Small op, + Dwarf_Unsigned val1, + Dwarf_Unsigned val2, Dwarf_Error * error) +{ + Dwarf_P_Frame_Pgm curinst; + int nbytes, nbytes1, nbytes2; + Dwarf_Ubyte db; + Dwarf_Half dh; + Dwarf_Word dw; + Dwarf_Unsigned du; + char *ptr; + int res; + char buff1[ENCODE_SPACE_NEEDED]; + char buff2[ENCODE_SPACE_NEEDED]; + Dwarf_P_Debug dbg = fde->fde_dbg; + + + nbytes = 0; + ptr = NULL; + curinst = (Dwarf_P_Frame_Pgm) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s)); + if (curinst == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_FPGM_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + + switch (op) { + + case DW_CFA_advance_loc: + if (val1 <= 0x3f) { + db = val1; + op |= db; + } + /* test not portable FIX */ + else if (val1 <= UCHAR_MAX) { + op = DW_CFA_advance_loc1; + db = val1; + ptr = (char *) _dwarf_p_get_alloc(dbg, 1); + if (ptr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + memcpy((void *) ptr, (const void *) &db, 1); + nbytes = 1; + } + /* test not portable FIX */ + else if (val1 <= USHRT_MAX) { + op = DW_CFA_advance_loc2; + dh = val1; + ptr = (char *) _dwarf_p_get_alloc(dbg, 2); + if (ptr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + memcpy((void *) ptr, (const void *) &dh, 2); + nbytes = 2; + } + /* test not portable FIX */ + else if (val1 <= ULONG_MAX) { + op = DW_CFA_advance_loc4; + dw = (Dwarf_Word) val1; + ptr = (char *) _dwarf_p_get_alloc(dbg, 4); + if (ptr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + memcpy((void *) ptr, (const void *) &dw, 4); + nbytes = 4; + } else { + op = DW_CFA_MIPS_advance_loc8; + du = val1; + ptr = + (char *) _dwarf_p_get_alloc(dbg, + sizeof(Dwarf_Unsigned)); + if (ptr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + memcpy((void *) ptr, (const void *) &du, 8); + nbytes = 8; + } + break; + + case DW_CFA_offset: + if (val1 <= MAX_6_BIT_VALUE) { + db = val1; + op |= db; + res = _dwarf_pro_encode_leb128_nm(val2, &nbytes, + buff1, sizeof(buff1)); + if (res != DW_DLV_OK) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); + if (ptr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + memcpy(ptr, buff1, nbytes); + + } else { + op = DW_CFA_offset_extended; + + res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1, + buff1, sizeof(buff1)); + if (res != DW_DLV_OK) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, + buff2, sizeof(buff2)); + if (res != DW_DLV_OK) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes1 + nbytes2); + if (ptr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + memcpy(ptr, buff1, nbytes1); + memcpy(ptr + nbytes1, buff2, nbytes2); + nbytes = nbytes1 + nbytes2; + } + break; + + case DW_CFA_undefined: + case DW_CFA_same_value: + res = _dwarf_pro_encode_leb128_nm(val1, &nbytes, + buff1, sizeof(buff1)); + if (res != DW_DLV_OK) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); + if (ptr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + memcpy(ptr, buff1, nbytes); + break; + + case DW_CFA_register: + case DW_CFA_def_cfa: + res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1, + buff1, sizeof(buff1)); + if (res != DW_DLV_OK) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + + res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, + buff2, sizeof(buff2)); + if (res != DW_DLV_OK) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + + ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes1 + nbytes2); + if (ptr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + memcpy(ptr, buff1, nbytes1); + memcpy(ptr + nbytes1, buff2, nbytes2); + nbytes = nbytes1 + nbytes2; + break; + + case DW_CFA_def_cfa_register: + case DW_CFA_def_cfa_offset: + res = _dwarf_pro_encode_leb128_nm(val1, &nbytes, + buff1, sizeof(buff1)); + if (res != DW_DLV_OK) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); + if (ptr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + memcpy(ptr, buff1, nbytes); + break; + + default: + /* This is wrong. We are just ignoring + instructions we don't yet handle. FIXME. */ + break; + } + + curinst->dfp_opcode = op; + curinst->dfp_args = ptr; + curinst->dfp_nbytes = nbytes; + curinst->dfp_next = NULL; + + _dwarf_pro_add_to_fde(fde, curinst); + return fde; +} + + +/*------------------------------------------------------------------------ + instructions are added to fde in the form of a linked + list. This function manages the linked list +-------------------------------------------------------------------------*/ +void +_dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm curinst) +{ + if (fde->fde_last_inst) { + fde->fde_last_inst->dfp_next = curinst; + fde->fde_last_inst = curinst; + fde->fde_n_inst++; + fde->fde_n_bytes += + (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte)); + } else { + fde->fde_last_inst = curinst; + fde->fde_inst = curinst; + fde->fde_n_inst = 1; + fde->fde_n_bytes = + (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte)); + } +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_frame.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_frame.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,127 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +/* + Largest register value that can be coded into + the opcode since there are only 6 bits in the + register field. +*/ +#define MAX_6_BIT_VALUE 0x3f + +/* + This struct holds debug_frame instructions +*/ +typedef struct Dwarf_P_Frame_Pgm_s *Dwarf_P_Frame_Pgm; + +struct Dwarf_P_Frame_Pgm_s { + Dwarf_Ubyte dfp_opcode; /* opcode - includes reg # */ + char *dfp_args; /* operands */ + int dfp_nbytes; /* number of bytes in args */ +#if 0 + Dwarf_Unsigned dfp_sym_index; /* 0 unless reloc needed */ +#endif + Dwarf_P_Frame_Pgm dfp_next; +}; + + +/* + This struct has cie related information. Used to gather data + from user program, and later to transform to disk form +*/ +struct Dwarf_P_Cie_s { + Dwarf_Ubyte cie_version; + char *cie_aug; /* augmentation */ + Dwarf_Ubyte cie_code_align; /* alignment of code */ + Dwarf_Sbyte cie_data_align; + Dwarf_Ubyte cie_ret_reg; /* return register # */ + char *cie_inst; /* initial instruction */ + long cie_inst_bytes; + /* no of init_inst */ + Dwarf_P_Cie cie_next; +}; + + +/* producer fields */ +struct Dwarf_P_Fde_s { + Dwarf_Unsigned fde_unused1; + + /* function/subr die for this fde */ + Dwarf_P_Die fde_die; + + /* index to asso. cie */ + Dwarf_Word fde_cie; + + /* Address of first location of the code this frame applies to If + fde_end_symbol non-zero, this represents the offset from the + symbol indicated by fde_r_symidx */ + Dwarf_Addr fde_initloc; + + /* Relocation symbol for address of the code this frame applies to. + */ + Dwarf_Unsigned fde_r_symidx; + + /* Bytes of instr for this fde, if known */ + Dwarf_Unsigned fde_addr_range; + + /* linked list of instructions we will put in fde. */ + Dwarf_P_Frame_Pgm fde_inst; + + /* number of instructions in fde */ + long fde_n_inst; + + /* number of bytes of inst in fde */ + long fde_n_bytes; + + /* offset into exception table for this function. */ + Dwarf_Signed fde_offset_into_exception_tables; + + /* The symbol for the exception table elf section. */ + Dwarf_Unsigned fde_exception_table_symbol; + + /* pointer to last inst */ + Dwarf_P_Frame_Pgm fde_last_inst; + + Dwarf_P_Fde fde_next; + + /* The symbol and offset of the end symbol. When fde_end_symbol is + non-zero we must represent the */ + Dwarf_Addr fde_end_symbol_offset; + Dwarf_Unsigned fde_end_symbol; + + int fde_uwordb_size; + Dwarf_P_Debug fde_dbg; +}; diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_funcs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_funcs.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,62 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#endif +#include "pro_incl.h" +#include "pro_section.h" + +/* + This function adds another function name to the + list of function names for the given Dwarf_P_Debug. + It returns 0 on error, and 1 otherwise. +*/ +Dwarf_Unsigned +dwarf_add_funcname(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *function_name, Dwarf_Error * error) +{ + return + _dwarf_add_simple_name_entry(dbg, die, function_name, + dwarf_snk_funcname, error); + +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_incl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_incl.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,92 @@ +/* + + Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + +#ifdef HAVE_ELF_H +#include +#elif defined(HAVE_LIBELF_H) +/* On one platform without elf.h this gets Elf32_Rel + type defined (a required type). */ +#include +#endif + +#if defined(sun) +#include +#include +#endif + +/* The target address is given: the place in the source integer + is to be determined. +*/ +#ifdef WORDS_BIGENDIAN +#define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ + { \ + dbg->de_copy_word(dest, \ + ((char *)source) +srclength-len_out, \ + len_out) ; \ + } + + +#else /* LITTLE ENDIAN */ + +#define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ + { \ + dbg->de_copy_word( (dest) , \ + ((char *)source) , \ + len_out) ; \ + } +#endif + + +#if defined(sparc) && defined(sun) +#define REL32 Elf32_Rela +#define REL64 Elf64_Rela +#define REL_SEC_PREFIX ".rela" +#else +#define REL32 Elf32_Rel +#define REL64 Elf64_Rel +#define REL_SEC_PREFIX ".rel" +#endif + + +#include "libdwarf.h" + +#include "dwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_util.h" +#include "pro_encode_nm.h" +#include "pro_alloc.h" diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_init.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_init.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,251 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#include "pro_incl.h" +#include "pro_section.h" /* for MAGIC_SECT_NO */ +#include "pro_reloc_symbolic.h" +#include "pro_reloc_stream.h" + + +static void common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags); + +void *_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len); + +/*-------------------------------------------------------------------- + This function sets up a new dwarf producing region. + flags: Indicates type of access method, one of DW_DLC* macros + func(): Used to create a new object file, a call back function + errhand(): Error Handler provided by user + errarg: Argument to errhand() + error: returned error value +--------------------------------------------------------------------*/ + /* We want the following to have an elf section number that matches + 'nothing' */ +static struct Dwarf_P_Section_Data_s init_sect = { + MAGIC_SECT_NO, 0, 0, 0, 0 +}; + +Dwarf_P_Debug +dwarf_producer_init_b(Dwarf_Unsigned flags, + Dwarf_Callback_Func_b func, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, Dwarf_Error * error) +{ + Dwarf_P_Debug dbg; + dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL, + sizeof(struct + Dwarf_P_Debug_s)); + if (dbg == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, + (Dwarf_P_Debug) DW_DLV_BADADDR); + } + memset((void *) dbg, 0, sizeof(struct Dwarf_P_Debug_s)); + /* For the time being */ + if (func == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC, + (Dwarf_P_Debug) DW_DLV_BADADDR); + } + dbg->de_func_b = func; + dbg->de_errhand = errhand; + dbg->de_errarg = errarg; + common_init(dbg, flags); + return dbg; + +} + +Dwarf_P_Debug +dwarf_producer_init(Dwarf_Unsigned flags, + Dwarf_Callback_Func func, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, Dwarf_Error * error) +{ + + Dwarf_P_Debug dbg; + + + + dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL, + sizeof(struct + Dwarf_P_Debug_s)); + if (dbg == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, + (Dwarf_P_Debug) DW_DLV_BADADDR); + } + memset((void *) dbg, 0, sizeof(struct Dwarf_P_Debug_s)); + /* For the time being */ + if (func == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC, + (Dwarf_P_Debug) DW_DLV_BADADDR); + } + dbg->de_func = func; + dbg->de_errhand = errhand; + dbg->de_errarg = errarg; + common_init(dbg, flags); + return dbg; +} +static void +common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags) +{ + unsigned int k; + + + dbg->de_version_magic_number = PRO_VERSION_MAGIC; + dbg->de_n_debug_sect = 0; + dbg->de_debug_sects = &init_sect; + dbg->de_current_active_section = &init_sect; + dbg->de_flags = flags; + + /* Now, with flags set, can use 64bit tests */ + + + +#if defined(HAVE_DWARF2_99_EXTENSION) + /* Revised 64 bit output, using distingushed values. Per 1999 + dwarf2 revision This produces 64bit extension with ia64 objects. + + Some might want library run time selection of offset size. Not + provided here at present. */ + dbg->de_64bit_extension = (IS_64BIT(dbg) ? 1 : 0); + dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4); + dbg->de_offset_size = (IS_64BIT(dbg) ? 8 : 4); + dbg->de_ptr_reloc = + IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg); + /* Non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit + pointer environments. */ + /* Get_REL??_isa here supports 64bit-offset dwarf. For 64bit, we + emit the extension bytes. */ + + dbg->de_offset_reloc = IS_64BIT(dbg) ? Get_REL64_isa(dbg) + : Get_REL32_isa(dbg); +#elif defined(HAVE_OLD_DWARF2_32BIT_OFFSET) + /* This is cygnus 32bit offset, as specified in pure dwarf2 v2.0.0 */ + dbg->de_64bit_extension = 0; + dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4); + dbg->de_offset_size = (IS_64BIT(dbg) ? 4 : 4); + dbg->de_ptr_reloc = + IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg); + /* non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit + pointer environments. */ + /* Get_REL32_isa here supports 64-bit-pointer dwarf with pure + dwarf2 v2.0.0 32bit offsets, as emitted by cygnus tools. And + pure 32 bit offset dwarf for 32bit pointer apps. */ + + dbg->de_offset_reloc = Get_REL32_isa(dbg); +#else + /* MIPS-SGI 32 or 64, where offsets and lengths are both 64 bit for + 64bit pointer objects and both 32 bit for 32bit pointer objects. + And a dwarf-reader must check elf info to tell which applies. */ + dbg->de_64bit_extension = 0; + dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4); + dbg->de_offset_size = (IS_64BIT(dbg) ? 8 : 4); + dbg->de_ptr_reloc = + IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg); + dbg->de_offset_reloc = dbg->de_ptr_reloc; +#endif + dbg->de_exc_reloc = Get_REL_SEGREL_isa(dbg); + + dbg->de_is_64bit = IS_64BIT(dbg); + + + if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) { + dbg->de_relocation_record_size = + sizeof(struct Dwarf_Relocation_Data_s); + } else { + +#if HAVE_ELF64_GETEHDR + dbg->de_relocation_record_size = + IS_64BIT(dbg)? sizeof(REL64) : sizeof(REL32); +#else + dbg->de_relocation_record_size = sizeof(REL32); +#endif + + } + + if (dbg->de_offset_size == 8) { + dbg->de_ar_data_attribute_form = DW_FORM_data8; + dbg->de_ar_ref_attr_form = DW_FORM_ref8; + } else { + dbg->de_ar_data_attribute_form = DW_FORM_data4; + dbg->de_ar_ref_attr_form = DW_FORM_ref4; + } + + if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) { + dbg->de_reloc_name = _dwarf_pro_reloc_name_symbolic; + dbg->de_reloc_pair = _dwarf_pro_reloc_length_symbolic; + dbg->de_transform_relocs_to_disk = + _dwarf_symbolic_relocs_to_disk; + } else { + if (IS_64BIT(dbg)) { + dbg->de_reloc_name = _dwarf_pro_reloc_name_stream64; + } else { + dbg->de_reloc_name = _dwarf_pro_reloc_name_stream32; + } + dbg->de_reloc_pair = 0; + dbg->de_transform_relocs_to_disk = _dwarf_stream_relocs_to_disk; + } + for (k = 0; k < NUM_DEBUG_SECTIONS; ++k) { + + Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[k]; + + prel->pr_slots_per_block_to_alloc = DEFAULT_SLOTS_PER_BLOCK; + } + /* First assume host, target same endianness */ + dbg->de_same_endian = 1; + dbg->de_copy_word = memcpy; +#ifdef WORDS_BIGENDIAN + /* host is big endian, so what endian is target? */ + if (flags & DW_DLC_TARGET_LITTLEENDIAN) { + dbg->de_same_endian = 0; + dbg->de_copy_word = _dwarf_memcpy_swap_bytes; + } +#else /* little endian */ + /* host is little endian, so what endian is target? */ + if (flags & DW_DLC_TARGET_BIGENDIAN) { + dbg->de_same_endian = 0; + dbg->de_copy_word = _dwarf_memcpy_swap_bytes; + } +#endif /* !WORDS_BIGENDIAN */ + + + return; + +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_line.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_line.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,300 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELF_H +#include +#endif +#include "pro_incl.h" +#include "pro_line.h" + +Dwarf_Unsigned _dwarf_pro_add_line_entry(Dwarf_P_Debug, + Dwarf_Unsigned file_index, + Dwarf_Addr code_address, + Dwarf_Unsigned symidx, + Dwarf_Unsigned line_no, + Dwarf_Signed col_no, + Dwarf_Bool is_stmt_begin, + Dwarf_Bool is_bb_begin, + Dwarf_Ubyte opc, + Dwarf_Error * error); + +/*------------------------------------------------------------------------- + Add a entry to the line information section + file_index: index of file in file entries, obtained from + add_file_entry() call. + + This function actually calls _dwarf_pro_add_line_entry(), with + an extra parameter, the opcode. Done so that interface calls + dwarf_lne_set_address() and dwarf_lne_end_sequence() can use + this internal routine. +---------------------------------------------------------------------------*/ +Dwarf_Unsigned +dwarf_add_line_entry(Dwarf_P_Debug dbg, + Dwarf_Unsigned file_index, + Dwarf_Addr code_address, + Dwarf_Unsigned line_no, + Dwarf_Signed col_no, + Dwarf_Bool is_stmt_begin, + Dwarf_Bool is_bb_begin, Dwarf_Error * error) +{ + Dwarf_Unsigned retval; + + retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address, 0, + line_no, col_no, is_stmt_begin, + is_bb_begin, 0, error); + return retval; +} + +/*------------------------------------------------------------------------ + Ask to emit DW_LNE_set_address opcode explicitly. Used by be + to emit start of a new .text section, or to force a relocated + address into debug line information entry. +-------------------------------------------------------------------------*/ +Dwarf_Unsigned +dwarf_lne_set_address(Dwarf_P_Debug dbg, + Dwarf_Addr offs, + Dwarf_Unsigned symidx, Dwarf_Error * error) +{ + Dwarf_Ubyte opc; + Dwarf_Unsigned retval; + + opc = DW_LNE_set_address; + retval = + _dwarf_pro_add_line_entry(dbg, 0, offs, symidx, 0, 0, 0, 0, opc, + error); + return retval; +} + +/*------------------------------------------------------------------------ + Ask to emit end_seqence opcode. Used normally at the end of a + compilation unit. Can also be used in the middle if there + are gaps in the region described by the code address. +-------------------------------------------------------------------------*/ +Dwarf_Unsigned +dwarf_lne_end_sequence(Dwarf_P_Debug dbg, + Dwarf_Addr end_address, Dwarf_Error * error) +{ + Dwarf_Ubyte opc; + Dwarf_Unsigned retval; + + opc = DW_LNE_end_sequence; + retval = + _dwarf_pro_add_line_entry(dbg, 0, end_address, 0, 0, 0, 0, 0, + opc, error); + return retval; +} + +/*---------------------------------------------------------------------------- + Add an entry in the internal list of lines mantained by producer. + Opc indicates if an opcode needs to be generated, rather than just + an entry in the matrix. During opcodes generation time, these + opcodes will be used. +-----------------------------------------------------------------------------*/ +Dwarf_Unsigned +_dwarf_pro_add_line_entry(Dwarf_P_Debug dbg, + Dwarf_Unsigned file_index, + Dwarf_Addr code_address, + Dwarf_Unsigned symidx, + Dwarf_Unsigned line_no, + Dwarf_Signed col_no, + Dwarf_Bool is_stmt_begin, + Dwarf_Bool is_bb_begin, + Dwarf_Ubyte opc, Dwarf_Error * error) +{ + if (dbg->de_lines == NULL) { + dbg->de_lines = (Dwarf_P_Line) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s)); + if (dbg->de_lines == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_NOCOUNT); + } + dbg->de_last_line = dbg->de_lines; + _dwarf_pro_reg_init(dbg->de_lines); + + } else { + dbg->de_last_line->dpl_next = (Dwarf_P_Line) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s)); + if (dbg->de_last_line->dpl_next == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_NOCOUNT); + } + dbg->de_last_line = dbg->de_last_line->dpl_next; + _dwarf_pro_reg_init(dbg->de_last_line); + } + dbg->de_last_line->dpl_address = code_address; + dbg->de_last_line->dpl_file = (unsigned long) file_index; + dbg->de_last_line->dpl_line = (unsigned long) line_no; + dbg->de_last_line->dpl_column = (unsigned long) col_no; + dbg->de_last_line->dpl_is_stmt = is_stmt_begin; + dbg->de_last_line->dpl_basic_block = is_bb_begin; + dbg->de_last_line->dpl_opc = opc; + dbg->de_last_line->dpl_r_symidx = symidx; + + return (0); +} + +/*----------------------------------------------------------------------- + Add a directory declaration to the debug_line section. Stored + in linked list. +------------------------------------------------------------------------*/ +Dwarf_Unsigned +dwarf_add_directory_decl(Dwarf_P_Debug dbg, + char *name, Dwarf_Error * error) +{ + if (dbg->de_inc_dirs == NULL) { + dbg->de_inc_dirs = (Dwarf_P_Inc_Dir) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s)); + if (dbg->de_inc_dirs == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_NOCOUNT); + } + dbg->de_last_inc_dir = dbg->de_inc_dirs; + dbg->de_n_inc_dirs = 1; + } else { + dbg->de_last_inc_dir->did_next = (Dwarf_P_Inc_Dir) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s)); + if (dbg->de_last_inc_dir->did_next == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_NOCOUNT); + } + dbg->de_last_inc_dir = dbg->de_last_inc_dir->did_next; + dbg->de_n_inc_dirs++; + } + dbg->de_last_inc_dir->did_name = + (char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1); + if (dbg->de_last_inc_dir->did_name == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_STRING_ALLOC, DW_DLV_NOCOUNT); + } + strcpy(dbg->de_last_inc_dir->did_name, name); + dbg->de_last_inc_dir->did_next = NULL; + + return dbg->de_n_inc_dirs; +} + +/*----------------------------------------------------------------------- + Add a file entry declaration to the debug_line section. Stored + in linked list. The data is immediately encodes as leb128 + and stored in Dwarf_P_F_Entry_s struct. +------------------------------------------------------------------------*/ +Dwarf_Unsigned +dwarf_add_file_decl(Dwarf_P_Debug dbg, + char *name, + Dwarf_Unsigned dir_idx, + Dwarf_Unsigned time_mod, + Dwarf_Unsigned length, Dwarf_Error * error) +{ + Dwarf_P_F_Entry cur; + char *ptr; + int nbytes_idx, nbytes_time, nbytes_len; + char buffidx[ENCODE_SPACE_NEEDED]; + char bufftime[ENCODE_SPACE_NEEDED]; + char bufflen[ENCODE_SPACE_NEEDED]; + int res; + + if (dbg->de_file_entries == NULL) { + dbg->de_file_entries = (Dwarf_P_F_Entry) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s)); + if (dbg->de_file_entries == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC, + DW_DLV_NOCOUNT); + } + cur = dbg->de_file_entries; + dbg->de_last_file_entry = cur; + dbg->de_n_file_entries = 1; + } else { + cur = dbg->de_last_file_entry; + cur->dfe_next = (Dwarf_P_F_Entry) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s)); + if (cur->dfe_next == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC, + DW_DLV_NOCOUNT); + } + cur = cur->dfe_next; + dbg->de_last_file_entry = cur; + dbg->de_n_file_entries++; + } + cur->dfe_name = (char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1); + if (cur->dfe_name == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT); + } + strcpy((char *) cur->dfe_name, name); + res = _dwarf_pro_encode_leb128_nm(dir_idx, &nbytes_idx, + buffidx, sizeof(buffidx)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT); + } + res = _dwarf_pro_encode_leb128_nm(time_mod, &nbytes_time, + bufftime, sizeof(bufftime)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT); + } + res = _dwarf_pro_encode_leb128_nm(length, &nbytes_len, + bufflen, sizeof(bufflen)); + cur->dfe_args = (char *) + _dwarf_p_get_alloc(dbg, nbytes_idx + nbytes_time + nbytes_len); + if (cur->dfe_args == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT); + } + ptr = cur->dfe_args; + memcpy((void *) ptr, buffidx, nbytes_idx); + ptr += nbytes_idx; + memcpy((void *) ptr, bufftime, nbytes_time); + ptr += nbytes_time; + memcpy((void *) ptr, bufflen, nbytes_len); + ptr += nbytes_len; + cur->dfe_nbytes = nbytes_idx + nbytes_time + nbytes_len; + cur->dfe_next = NULL; + + return dbg->de_n_file_entries; +} + + +/*--------------------------------------------------------------------- + Initialize a row of the matrix for line numbers, meaning + initialize the struct corresponding to it +----------------------------------------------------------------------*/ +void +_dwarf_pro_reg_init(Dwarf_P_Line cur_line) +{ + cur_line->dpl_address = 0; + cur_line->dpl_file = 1; + cur_line->dpl_line = 1; + cur_line->dpl_column = 0; + cur_line->dpl_is_stmt = DEFAULT_IS_STMT; + cur_line->dpl_basic_block = false; + cur_line->dpl_next = NULL; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_line.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_line.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,116 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#define VERSION 2 +#ifdef __i386 +#define MIN_INST_LENGTH 1 +#else +#define MIN_INST_LENGTH 4 +#endif +#define DEFAULT_IS_STMT false + /* line base and range are temporarily defines. + They need to be calculated later */ +#define LINE_BASE -1 +#define LINE_RANGE 4 + +#define OPCODE_BASE 10 +#define MAX_OPCODE 255 + + +/* + This struct is used to hold entries in the include directories + part of statement prologue. +*/ +struct Dwarf_P_Inc_Dir_s { + char *did_name; /* name of directory */ + Dwarf_P_Inc_Dir did_next; +}; + + +/* + This struct holds file entries for the statement prologue. + Defined in pro_line.h +*/ +struct Dwarf_P_F_Entry_s { + char *dfe_name; + char *dfe_args; /* has dir index, time of modification, + length in bytes. Encodes as leb128 */ + int dfe_nbytes; /* number of bytes in args */ + Dwarf_P_F_Entry dfe_next; +}; + + +/* + Struct holding line number information for each of the producer + line entries +*/ +struct Dwarf_P_Line_s { + /* code address */ + Dwarf_Addr dpl_address; + + /* file index, index into file entry */ + Dwarf_Word dpl_file; + + /* line number */ + Dwarf_Word dpl_line; + + /* column number */ + Dwarf_Word dpl_column; + + /* whether its a beginning of a stmt */ + Dwarf_Ubyte dpl_is_stmt; + + /* whether its a beginning of basic blk */ + Dwarf_Ubyte dpl_basic_block; + + /* used to store opcodes set_address, and end_seq */ + Dwarf_Ubyte dpl_opc; + + /* + Used only for relocations. Has index of symbol relative to + which relocation has to be done (the S part in S + A) */ + Dwarf_Unsigned dpl_r_symidx; + + Dwarf_P_Line dpl_next; +}; + +/* + to initialize state machine registers, definition in + pro_line.c +*/ +void _dwarf_pro_reg_init(Dwarf_P_Line); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_macinfo.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_macinfo.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,472 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#include "pro_incl.h" +#include "pro_section.h" +#include "pro_macinfo.h" + +/* + I don't much like the error strings this generates, since + like the rest of libdwarf they are simple strings with + no useful numbers in them. But that's not something I can + fix without more work than I have time for + right now. davea Nov 94. +*/ + +/* these are gross overestimates of the number of +** bytes needed to store a number in LEB form. +** Just estimates, and since blocks are reasonable size, +** the end-block waste is small. +** Of course the waste is NOT present on disk. +*/ + +#define COMMAND_LEN ENCODE_SPACE_NEEDED +#define LINE_LEN ENCODE_SPACE_NEEDED +#define BASE_MACINFO_MALLOC_LEN 2048 + +static int +libdwarf_compose_begin(Dwarf_P_Debug dbg, int code, + size_t maxlen, int *compose_error_type) +{ + unsigned char *nextchar; + struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; + + if (curblk == 0) { + struct dw_macinfo_block_s *newb; + size_t len; + + /* initial allocation */ + size_t blen = BASE_MACINFO_MALLOC_LEN; + + if (blen < maxlen) { + blen = 2 * maxlen; + } + len = sizeof(struct dw_macinfo_block_s) + blen; + newb = + (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len); + if (!newb) { + *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL; + return DW_DLV_ERROR; + } + newb->mb_data = + (char *) newb + sizeof(struct dw_macinfo_block_s); + newb->mb_avail_len = blen; + newb->mb_used_len = 0; + newb->mb_macinfo_data_space_len = blen; + dbg->de_first_macinfo = newb; + dbg->de_current_macinfo = newb; + curblk = newb; + } else if (curblk->mb_avail_len < maxlen) { + struct dw_macinfo_block_s *newb; + size_t len; + + /* no space left in block: allocate a new block */ + size_t blen = + dbg->de_current_macinfo->mb_macinfo_data_space_len * 2; + if (blen < maxlen) { + blen = 2 * maxlen; + } + len = sizeof(struct dw_macinfo_block_s) + blen; + newb = + (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len); + if (!newb) { + *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL; + return DW_DLV_ERROR; + } + newb->mb_data = + (char *) newb + sizeof(struct dw_macinfo_block_s); + newb->mb_avail_len = blen; + newb->mb_used_len = 0; + newb->mb_macinfo_data_space_len = blen; + dbg->de_first_macinfo->mb_next = newb; + dbg->de_current_macinfo = newb; + curblk = newb; + } + /* now curblk has enough room */ + dbg->de_compose_avail = curblk->mb_avail_len; + dbg->de_compose_used_len = curblk->mb_used_len; + nextchar = + (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len); + *nextchar = code; + dbg->de_compose_avail--; + ++dbg->de_compose_used_len; + return DW_DLV_OK; +} + + + +static void +libdwarf_compose_add_string(Dwarf_P_Debug dbg, char *string, size_t len) +{ + struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; + unsigned char *nextchar; + + nextchar = + (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len); + + len += 1; /* count the null terminator */ + + memcpy(nextchar, string, len); + dbg->de_compose_avail -= len; + dbg->de_compose_used_len += len; + return; + +} +static int +libdwarf_compose_add_line(Dwarf_P_Debug dbg, + Dwarf_Unsigned line, int *compose_error_type) +{ + struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; + unsigned char *nextchar; + int res; + int nbytes; + + nextchar = + (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len); + + /* Put the created leb number directly into the macro buffer If + dbg->de_compose_avail is > INT_MAX this will not work as the + 'int' will look negative to _dwarf_pro_encode_leb128_nm! */ + + res = _dwarf_pro_encode_leb128_nm(line, &nbytes, + (char *) nextchar, + (int) dbg->de_compose_avail); + if (res != DW_DLV_OK) { + *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE; + return DW_DLV_ERROR; + } + + dbg->de_compose_avail -= nbytes; + dbg->de_compose_used_len += nbytes; + return DW_DLV_OK; +} + +/* + This function actually 'commits' the space used by the + preceeding calls. +*/ +static int +libdwarf_compose_complete(Dwarf_P_Debug dbg, int *compose_error_type) +{ + struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; + + if (dbg->de_compose_used_len > curblk->mb_macinfo_data_space_len) { + *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE; + return DW_DLV_ERROR; + } + curblk->mb_avail_len = dbg->de_compose_avail; + curblk->mb_used_len = dbg->de_compose_used_len; + return DW_DLV_OK; +} + + + +int +dwarf_def_macro(Dwarf_P_Debug dbg, + Dwarf_Unsigned line, + char *macname, char *macvalue, Dwarf_Error * error) +{ + size_t len; + size_t len2; + size_t length_est; + int res; + int compose_error_type; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + if (macname == 0) { + _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL); + return (DW_DLV_ERROR); + } + len = strlen(macname) + 1; + if (len == 0) { + _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY); + return (DW_DLV_ERROR); + } + if (macvalue) { + len2 = strlen(macvalue) + 1; + } else { + len2 = 0; + } + length_est = COMMAND_LEN + LINE_LEN + len + len2 + 1; /* 1 + for + space + character + we + add */ + res = libdwarf_compose_begin(dbg, DW_MACINFO_define, length_est, + &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + res = libdwarf_compose_add_line(dbg, line, &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + libdwarf_compose_add_string(dbg, macname, len); + libdwarf_compose_add_string(dbg, " ", 1); + if (macvalue) { + libdwarf_compose_add_string(dbg, " ", 1); + libdwarf_compose_add_string(dbg, macvalue, len2); + } + res = libdwarf_compose_complete(dbg, &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + return DW_DLV_OK; +} + +int +dwarf_undef_macro(Dwarf_P_Debug dbg, + Dwarf_Unsigned line, + char *macname, Dwarf_Error * error) +{ + + size_t len; + size_t length_est; + int res; + int compose_error_type; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + if (macname == 0) { + _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL); + return (DW_DLV_ERROR); + } + len = strlen(macname) + 1; + if (len == 0) { + _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY); + return (DW_DLV_ERROR); + } + length_est = COMMAND_LEN + LINE_LEN + len; + res = libdwarf_compose_begin(dbg, DW_MACINFO_undef, length_est, + &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + res = libdwarf_compose_add_line(dbg, line, &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + libdwarf_compose_add_string(dbg, macname, len); + res = libdwarf_compose_complete(dbg, &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + return DW_DLV_OK; +} + +int +dwarf_start_macro_file(Dwarf_P_Debug dbg, + Dwarf_Unsigned fileindex, + Dwarf_Unsigned linenumber, Dwarf_Error * error) +{ + size_t length_est; + int res; + int compose_error_type; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + length_est = COMMAND_LEN + LINE_LEN + LINE_LEN; + res = libdwarf_compose_begin(dbg, DW_MACINFO_start_file, length_est, + &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + res = libdwarf_compose_add_line(dbg, fileindex, + &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + res = libdwarf_compose_add_line(dbg, linenumber, + &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + return DW_DLV_OK; +} + +int +dwarf_end_macro_file(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + size_t length_est; + int res; + int compose_error_type; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + length_est = COMMAND_LEN; + res = libdwarf_compose_begin(dbg, DW_MACINFO_end_file, length_est, + &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + res = libdwarf_compose_complete(dbg, &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + return DW_DLV_OK; +} + +int +dwarf_vendor_ext(Dwarf_P_Debug dbg, + Dwarf_Unsigned constant, + char *string, Dwarf_Error * error) +{ + size_t len; + size_t length_est; + int res; + int compose_error_type; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + if (string == 0) { + _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL); + return (DW_DLV_ERROR); + } + len = strlen(string) + 1; + if (len == 0) { + _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY); + return (DW_DLV_ERROR); + } + length_est = COMMAND_LEN + LINE_LEN + len; + res = libdwarf_compose_begin(dbg, DW_MACINFO_vendor_ext, length_est, + &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + res = libdwarf_compose_add_line(dbg, constant, &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + libdwarf_compose_add_string(dbg, string, len); + libdwarf_compose_complete(dbg, &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + return DW_DLV_OK; +} + + + +int +_dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg, + Dwarf_Error * error) +{ + /* Total num of bytes in .debug_macinfo section. */ + Dwarf_Unsigned mac_num_bytes; + + /* Points to first byte of .debug_macinfo buffer. */ + Dwarf_Small *macinfo; + + /* Fills in the .debug_macinfo buffer. */ + Dwarf_Small *macinfo_ptr; + + + /* Used to scan the section data buffers. */ + struct dw_macinfo_block_s *m_prev; + struct dw_macinfo_block_s *m_sect; + + + /* Get the size of the debug_macinfo data */ + mac_num_bytes = 0; + for (m_sect = dbg->de_first_macinfo; m_sect != NULL; + m_sect = m_sect->mb_next) { + mac_num_bytes += m_sect->mb_used_len; + } + /* Tthe final entry has a type code of 0 to indicate It is final + for this CU Takes just 1 byte. */ + mac_num_bytes += 1; + + GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_MACINFO], + macinfo, (unsigned long) mac_num_bytes, error); + if (macinfo == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (0); + } + + macinfo_ptr = macinfo; + m_prev = 0; + for (m_sect = dbg->de_first_macinfo; m_sect != NULL; + m_sect = m_sect->mb_next) { + memcpy(macinfo_ptr, m_sect->mb_data, m_sect->mb_used_len); + macinfo_ptr += m_sect->mb_used_len; + if (m_prev) { + _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev); + m_prev = 0; + } + m_prev = m_sect; + } + *macinfo_ptr = 0; /* the type code of 0 as last entry */ + if (m_prev) { + _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev); + m_prev = 0; + } + + dbg->de_first_macinfo = NULL; + dbg->de_current_macinfo = NULL; + + return (int) dbg->de_n_debug_sect; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_macinfo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_macinfo.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,40 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + + +int _dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg, + Dwarf_Error * error); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_opaque.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_opaque.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,514 @@ +/* + + Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + +#include + +/* + Sgidefs included to define __uint32_t, + a guaranteed 4-byte quantity. +*/ +#include "libdwarfdefs.h" + +#define true 1 +#define false 0 + +/* to identify a cie */ +#define DW_CIE_ID ~(0x0) +#define DW_CIE_VERSION 1 + +/*Dwarf_Word is unsigned word usable for index, count in memory */ +/*Dwarf_Sword is signed word usable for index, count in memory */ +/* The are 32 or 64 bits depending if 64 bit longs or not, which +** fits the ILP32 and LP64 models +** These work equally well with ILP64. +*/ + +typedef unsigned long Dwarf_Word; +typedef long Dwarf_Sword; + + +typedef signed char Dwarf_Sbyte; +typedef unsigned char Dwarf_Ubyte; +typedef signed short Dwarf_Shalf; + +/* + On any change that makes libdwarf producer + incompatible, increment this number. + 1->2->3 ... + +*/ +#define PRO_VERSION_MAGIC 0xdead1 + + +/* these 2 are fixed sizes which must not vary with the +** ILP32/LP64 model. These two stay at 32 bit. +*/ +typedef __uint32_t Dwarf_ufixed; +typedef __int32_t Dwarf_sfixed; + +/* + producer: + This struct is used to hold information about all + debug* sections. On creating a new section, section + names and indices are added to this struct + definition in pro_section.h +*/ +typedef struct Dwarf_P_Section_Data_s *Dwarf_P_Section_Data; + +/* + producer: + This struct is used to hold entries in the include directories + part of statement prologue. Definition in pro_line.h +*/ +typedef struct Dwarf_P_Inc_Dir_s *Dwarf_P_Inc_Dir; + +/* + producer: + This struct holds file entries for the statement prologue. + Defined in pro_line.h +*/ +typedef struct Dwarf_P_F_Entry_s *Dwarf_P_F_Entry; + +/* + producer: + This struct holds information for each cie. Defn in pro_frame.h +*/ +typedef struct Dwarf_P_Cie_s *Dwarf_P_Cie; + +/* + producer: + Struct to hold line number information, different from + Dwarf_Line opaque type. +*/ +typedef struct Dwarf_P_Line_s *Dwarf_P_Line; + +/* + producer: + Struct to hold information about address ranges. +*/ +typedef struct Dwarf_P_Simple_nameentry_s *Dwarf_P_Simple_nameentry; +typedef struct Dwarf_P_Simple_name_header_s *Dwarf_P_Simple_name_header; +typedef struct Dwarf_P_Arange_s *Dwarf_P_Arange; +typedef struct Dwarf_P_Per_Reloc_Sect_s *Dwarf_P_Per_Reloc_Sect; +typedef struct Dwarf_P_Per_Sect_String_Attrs_s *Dwarf_P_Per_Sect_String_Attrs; + +/* Defined to get at the elf section numbers and section name + indices in symtab for the dwarf sections + Must match .rel.* names in _dwarf_rel_section_names + exactly. +*/ +#define DEBUG_INFO 0 +#define DEBUG_LINE 1 +#define DEBUG_ABBREV 2 +#define DEBUG_FRAME 3 +#define DEBUG_ARANGES 4 +#define DEBUG_PUBNAMES 5 +#define DEBUG_STR 6 +#define DEBUG_FUNCNAMES 7 +#define DEBUG_TYPENAMES 8 +#define DEBUG_VARNAMES 9 +#define DEBUG_WEAKNAMES 10 +#define DEBUG_MACINFO 11 +#define DEBUG_LOC 12 + + /* number of debug_* sections not including the relocations */ +#define NUM_DEBUG_SECTIONS DEBUG_LOC + 1 + + +struct Dwarf_P_Die_s { + Dwarf_Unsigned di_offset; /* offset in debug info */ + char *di_abbrev; /* abbreviation */ + Dwarf_Word di_abbrev_nbytes; /* # of bytes in abbrev */ + Dwarf_Tag di_tag; + Dwarf_P_Die di_parent; /* parent of current die */ + Dwarf_P_Die di_child; /* first child */ + Dwarf_P_Die di_left; /* left sibling */ + Dwarf_P_Die di_right; /* right sibling */ + Dwarf_P_Attribute di_attrs; /* list of attributes */ + Dwarf_P_Attribute di_last_attr; /* last attribute */ + int di_n_attr; /* number of attributes */ + Dwarf_P_Debug di_dbg; /* For memory management */ + Dwarf_Unsigned di_marker; /* used to attach symbols to dies */ +}; + + +/* producer fields */ +struct Dwarf_P_Attribute_s { + Dwarf_Half ar_attribute; /* Attribute Value. */ + Dwarf_Half ar_attribute_form; /* Attribute Form. */ + Dwarf_P_Die ar_ref_die; /* die pointer if form ref */ + char *ar_data; /* data, format given by form */ + Dwarf_Unsigned ar_nbytes; /* no. of bytes of data */ + Dwarf_Unsigned ar_rel_symidx; /* when attribute has a + relocatable value, holds + index of symbol in SYMTAB */ + Dwarf_Ubyte ar_rel_type; /* relocation type */ + Dwarf_Word ar_rel_offset; /* Offset of relocation within block */ + char ar_reloc_len; /* Number of bytes that relocation + applies to. 4 or 8. Unused and may + be 0 if if ar_rel_type is + R_MIPS_NONE */ + Dwarf_P_Attribute ar_next; +}; + +/* A block of .debug_macinfo data: this forms a series of blocks. +** Each macinfo input is compressed immediately and put into +** the current block if room, else a newblock allocated. +** The space allocation is such that the block and the macinfo +** data are one malloc block: free with a pointer to this and the +** mb_data is freed automatically. +** Like the struct hack, but legal ANSI C. +*/ +struct dw_macinfo_block_s { + struct dw_macinfo_block_s *mb_next; + unsigned long mb_avail_len; + unsigned long mb_used_len; + unsigned long mb_macinfo_data_space_len; + char *mb_data; /* original malloc ptr. */ +}; + +/* dwarf_sn_kind is for the array of similarly-treated + name -> cu ties +*/ +enum dwarf_sn_kind { dwarf_snk_pubname, dwarf_snk_funcname, + dwarf_snk_weakname, dwarf_snk_typename, + dwarf_snk_varname, + dwarf_snk_entrycount /* this one must be last */ +}; + + + +/* The calls to add a varname etc use a list of + these as the list. +*/ +struct Dwarf_P_Simple_nameentry_s { + Dwarf_P_Die sne_die; + char *sne_name; + int sne_name_len; + Dwarf_P_Simple_nameentry sne_next; +}; + +/* An array of these, each of which heads a list + of Dwarf_P_Simple_nameentry +*/ +struct Dwarf_P_Simple_name_header_s { + Dwarf_P_Simple_nameentry sn_head; + Dwarf_P_Simple_nameentry sn_tail; + Dwarf_Signed sn_count; + + /* length that will be generated, not counting fixed header or + trailer */ + Dwarf_Signed sn_net_len; +}; +typedef int (*_dwarf_pro_reloc_name_func_ptr) (Dwarf_P_Debug dbg, int sec_index, Dwarf_Unsigned offset, /* r_offset + */ + Dwarf_Unsigned symidx, + enum Dwarf_Rel_Type type, + int reltarget_length); + +typedef int (*_dwarf_pro_reloc_length_func_ptr) (Dwarf_P_Debug dbg, int sec_index, Dwarf_Unsigned offset, /* r_offset + */ + Dwarf_Unsigned + start_symidx, + Dwarf_Unsigned + end_symidx, + enum Dwarf_Rel_Type + type, + int reltarget_length); +typedef int (*_dwarf_pro_transform_relocs_func_ptr) (Dwarf_P_Debug dbg, + Dwarf_Signed * + new_sec_count); + +/* + Each slot in a block of slots could be: + a binary stream relocation entry (32 or 64bit relocation data) + a SYMBOLIC relocation entry. + During creation sometimes we create multiple chained blocks, + but sometimes we create a single long block. + Before returning reloc data to caller, + we switch to a single, long-enough, + block. + + We make counters here Dwarf_Unsigned so that we + get sufficient alignment. Since we use space after + the struct (at malloc time) for user data which + must have Dwarf_Unsigned alignment, this + struct must have that alignment too. + +*/ +struct Dwarf_P_Relocation_Block_s { + Dwarf_Unsigned rb_slots_in_block; /* slots in block, as created */ + Dwarf_Unsigned rb_next_slot_to_use; /* counter, start at 0. */ + struct Dwarf_P_Relocation_Block_s *rb_next; + char *rb_where_to_add_next; /* pointer to next slot (might be past + end, depending on + rb_next_slot_to_use) */ + char *rb_data; /* data area */ +}; + +/* One of these per potential relocation section + So one per actual dwarf section. + Left zeroed when not used (some sections have + no relocations). +*/ +struct Dwarf_P_Per_Reloc_Sect_s { + + + unsigned long pr_reloc_total_count; /* total number of entries + across all blocks */ + + unsigned long pr_slots_per_block_to_alloc; /* at Block alloc, this + is the default + number of slots to + use */ + + int pr_sect_num_of_reloc_sect; /* sect number returned by + de_func() or de_func_b() + call, this is the sect + number of the relocation + section. */ + + + /* singly-linked list. add at and ('last') with count of blocks */ + struct Dwarf_P_Relocation_Block_s *pr_first_block; + struct Dwarf_P_Relocation_Block_s *pr_last_block; + unsigned long pr_block_count; +}; + +#define DEFAULT_SLOTS_PER_BLOCK 3 + +typedef struct memory_list_s { + struct memory_list_s *prev; + struct memory_list_s *next; +} memory_list_t; + + +struct Dwarf_P_Per_Sect_String_Attrs_s { + int sect_sa_section_number; + unsigned sect_sa_n_alloc; + unsigned sect_sa_n_used; + Dwarf_P_String_Attr sect_sa_list; +}; + +/* Fields used by producer */ +struct Dwarf_P_Debug_s { + /* used to catch dso passing dbg to another DSO with incompatible + version of libdwarf See PRO_VERSION_MAGIC */ + int de_version_magic_number; + + Dwarf_Unsigned de_access; + Dwarf_Handler de_errhand; + Dwarf_Ptr de_errarg; + + /* + Call back function, used to create .debug* sections. Provided + by user. Only of these used per dbg. */ + Dwarf_Callback_Func de_func; + Dwarf_Callback_Func_b de_func_b; + + /* Flags from producer_init call */ + Dwarf_Unsigned de_flags; + + /* This holds information on debug section stream output, including + the stream data */ + Dwarf_P_Section_Data de_debug_sects; + + /* Pointer to the 'current active' section */ + Dwarf_P_Section_Data de_current_active_section; + + /* Number of debug data streams globs. */ + Dwarf_Word de_n_debug_sect; + + /* File entry information, null terminated singly-linked list */ + Dwarf_P_F_Entry de_file_entries; + Dwarf_P_F_Entry de_last_file_entry; + Dwarf_Unsigned de_n_file_entries; + + /* Has the directories used to search for source files */ + Dwarf_P_Inc_Dir de_inc_dirs; + Dwarf_P_Inc_Dir de_last_inc_dir; + Dwarf_Unsigned de_n_inc_dirs; + + /* Has all the line number info for the stmt program */ + Dwarf_P_Line de_lines; + Dwarf_P_Line de_last_line; + + /* List of cie's for the debug unit */ + Dwarf_P_Cie de_frame_cies; + Dwarf_P_Cie de_last_cie; + Dwarf_Unsigned de_n_cie; + + /* Singly-linked list of fde's for the debug unit */ + Dwarf_P_Fde de_frame_fdes; + Dwarf_P_Fde de_last_fde; + Dwarf_Unsigned de_n_fde; + + /* First die, leads to all others */ + Dwarf_P_Die de_dies; + + /* Pointer to list of strings */ + char *de_strings; + + /* Pointer to chain of aranges */ + Dwarf_P_Arange de_arange; + Dwarf_P_Arange de_last_arange; + Dwarf_Sword de_arange_count; + + /* macinfo controls. */ + /* first points to beginning of the list during creation */ + struct dw_macinfo_block_s *de_first_macinfo; + + /* current points to the current, unfilled, block */ + struct dw_macinfo_block_s *de_current_macinfo; + + + /* Pointer to the first section, to support reset_section_bytes */ + Dwarf_P_Section_Data de_first_debug_sect; + + /* handles pubnames, weaknames, etc. See dwarf_sn_kind in + pro_opaque.h */ + struct Dwarf_P_Simple_name_header_s + de_simple_name_headers[dwarf_snk_entrycount]; + + /* relocation data. not all sections will actally have relocation + info, of course */ + struct Dwarf_P_Per_Reloc_Sect_s de_reloc_sect[NUM_DEBUG_SECTIONS]; + int de_reloc_next_to_return; /* iterator on reloc sections + (SYMBOLIC output) */ + + /* used in remembering sections */ + int de_elf_sects[NUM_DEBUG_SECTIONS]; /* + elf sect number of + the section itself, + DEBUG_LINE for + example */ + + Dwarf_Unsigned de_sect_name_idx[NUM_DEBUG_SECTIONS]; /* section + name + index + or + handle + for + the + name + of + the + symbol + for + DEBUG_LINE + for + example + */ + + + + int de_offset_reloc; /* offset reloc type, R_MIPS_32 for + example. Specific to the ABI being + produced. Relocates offset size + field */ + int de_exc_reloc; /* reloc type specific to exception + table relocs. */ + int de_ptr_reloc; /* standard reloc type, R_MIPS_32 for + example. Specific to the ABI being + produced. relocates pointer size + field */ + + unsigned char de_offset_size; /* section offset. Here to + avoid test of abi in macro + at run time MIPS -n32 4, + -64 8. */ + + unsigned char de_pointer_size; /* size of pointer in target. + Here to avoid test of abi in + macro at run time MIPS -n32 + 4, -64 is 8. */ + + unsigned char de_is_64bit; /* non-zero if is 64bit. Else 32 bit: + used for passing this info as a flag + */ + unsigned char de_relocation_record_size; /* reloc record size + varies by ABI and + relocation-output + method (stream or + symbolic) */ + + unsigned char de_64bit_extension; /* non-zero if creating 64 bit + offsets using dwarf2-99 + extension proposal */ + + int de_ar_data_attribute_form; /* data8, data4 abi dependent */ + int de_ar_ref_attr_form; /* ref8 ref4 , abi dependent */ + + /* simple name relocations */ + _dwarf_pro_reloc_name_func_ptr de_reloc_name; + + /* relocations for a length, requiring a pair of symbols */ + _dwarf_pro_reloc_length_func_ptr de_reloc_pair; + + _dwarf_pro_transform_relocs_func_ptr de_transform_relocs_to_disk; + + /* following used for macro buffers */ + unsigned long de_compose_avail; + unsigned long de_compose_used_len; + + unsigned char de_same_endian; + void *(*de_copy_word) (void *, const void *, size_t); + + /* Add new fields at the END of this struct to preserve some hope + of sensible behavior on dbg passing between DSOs linked with + mismatched libdwarf producer versions. */ + + Dwarf_P_Marker de_markers; /* pointer to array of markers */ + unsigned de_marker_n_alloc; + unsigned de_marker_n_used; + int de_sect_sa_next_to_return; /* Iterator on sring attrib sects */ + /* String attributes data of each section. */ + struct Dwarf_P_Per_Sect_String_Attrs_s de_sect_string_attr[NUM_DEBUG_SECTIONS]; +}; + + +#define CURRENT_VERSION_STAMP 2 + +Dwarf_Unsigned _dwarf_add_simple_name_entry(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *entry_name, + enum dwarf_sn_kind + entrykind, + Dwarf_Error * error); + + +#define DISTINGUISHED_VALUE 0xffffffff /* 64bit extension flag */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_pubnames.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_pubnames.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,63 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#endif +#include "pro_incl.h" +#include "pro_section.h" + + +/* + This function adds another public name to the + list of public names for the given Dwarf_P_Debug. + It returns 0 on error, and 1 otherwise. +*/ + +Dwarf_Unsigned +dwarf_add_pubname(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *pubname_name, Dwarf_Error * error) +{ + return + _dwarf_add_simple_name_entry(dbg, die, pubname_name, + dwarf_snk_pubname, error); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,268 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +/*#include */ +#include "pro_incl.h" + + +/*Do initial alloc of newslots slots. + Fails only if malloc fails. + + Supposed to be called before any relocs allocated. + Ignored if after any allocated. + + Part of an optimization, so that for a known 'newslots' + relocations count we can preallocate the right size block. + Called from just 2 places. + + returns DW_DLV_OK or DW_DLV_ERROR +*/ +int +_dwarf_pro_pre_alloc_n_reloc_slots(Dwarf_P_Debug dbg, + int rel_sec_index, + Dwarf_Unsigned newslots) +{ + unsigned long len; + struct Dwarf_P_Relocation_Block_s *data; + Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[rel_sec_index]; + unsigned long slots_in_blk = (unsigned long) newslots; + unsigned long rel_rec_size = dbg->de_relocation_record_size; + + if (prel->pr_first_block) + return DW_DLV_OK; /* do nothing */ + + len = sizeof(struct Dwarf_P_Relocation_Block_s) + + slots_in_blk * rel_rec_size; + + + data = (struct Dwarf_P_Relocation_Block_s *) + _dwarf_p_get_alloc(dbg, len); + if (!data) { + return DW_DLV_ERROR; + } + data->rb_slots_in_block = slots_in_blk; /* could use default + here, as fallback in + case our origininal + estimate wrong. When + we call this we + presumably know what + we are doing, so + keep this count for + now */ + data->rb_next_slot_to_use = 0; + data->rb_where_to_add_next = + ((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s); + data->rb_data = data->rb_where_to_add_next; + + prel->pr_first_block = data; + prel->pr_last_block = data; + prel->pr_block_count = 1; + + + return DW_DLV_OK; +} + + +/*Do alloc of slots. + Fails only if malloc fails. + + Only allocator used. + + returns DW_DLV_OK or DW_DLV_ERROR +*/ +int +_dwarf_pro_alloc_reloc_slots(Dwarf_P_Debug dbg, int rel_sec_index) +{ + unsigned long len; + struct Dwarf_P_Relocation_Block_s *data; + Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[rel_sec_index]; + unsigned long slots_in_blk = prel->pr_slots_per_block_to_alloc; + unsigned long rel_rec_size = dbg->de_relocation_record_size; + + len = sizeof(struct Dwarf_P_Relocation_Block_s) + + slots_in_blk * rel_rec_size; + + data = (struct Dwarf_P_Relocation_Block_s *) + _dwarf_p_get_alloc(dbg, len); + if (!data) { + return DW_DLV_ERROR; + } + + if (prel->pr_first_block) { + prel->pr_last_block->rb_next = data; + prel->pr_last_block = data; + prel->pr_block_count += 1; + + } else { + + prel->pr_first_block = data; + prel->pr_last_block = data; + prel->pr_block_count = 1; + } + + data->rb_slots_in_block = slots_in_blk; + data->rb_next_slot_to_use = 0; + data->rb_where_to_add_next = + ((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s); + data->rb_data = data->rb_where_to_add_next; + + return DW_DLV_OK; + +} + +/* + Reserve a slot. return DW_DLV_OK if succeeds. + + Return DW_DLV_ERROR if fails (malloc error). + + Use the relrec_to_fill to pass back a pointer to + a slot space to use. +*/ +int +_dwarf_pro_reloc_get_a_slot(Dwarf_P_Debug dbg, + int base_sec_index, void **relrec_to_fill) +{ + struct Dwarf_P_Relocation_Block_s *data; + Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[base_sec_index]; + unsigned long rel_rec_size = dbg->de_relocation_record_size; + + char *ret_addr; + + data = prel->pr_last_block; + if ((data == 0) || + (data->rb_next_slot_to_use >= data->rb_slots_in_block)) { + int res; + + res = _dwarf_pro_alloc_reloc_slots(dbg, base_sec_index); + if (res != DW_DLV_OK) { + return res; + } + } + + data = prel->pr_last_block; + /* now we have an empty slot */ + ret_addr = data->rb_where_to_add_next; + + data->rb_where_to_add_next += rel_rec_size; + data->rb_next_slot_to_use += 1; + + prel->pr_reloc_total_count += 1; + + *relrec_to_fill = (void *) ret_addr; + + return DW_DLV_OK; + +} + +/* + On success returns count of + .rel.* sections that are symbolic + thru count_of_relocation_sections. + + On success, returns DW_DLV_OK. + + If this is not a 'symbolic' run, returns + DW_DLV_NO_ENTRY. + + No errors are possible. + + + + +*/ + + /*ARGSUSED*/ int +dwarf_get_relocation_info_count(Dwarf_P_Debug dbg, + Dwarf_Unsigned * + count_of_relocation_sections, + int *drd_buffer_version, + Dwarf_Error * error) +{ + if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) { + int i; + unsigned int count = 0; + + for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) { + if (dbg->de_reloc_sect[i].pr_reloc_total_count > 0) { + ++count; + } + } + *count_of_relocation_sections = (Dwarf_Unsigned) count; + *drd_buffer_version = DWARF_DRD_BUFFER_VERSION; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} + +int +dwarf_get_relocation_info(Dwarf_P_Debug dbg, + Dwarf_Signed * elf_section_index, + Dwarf_Signed * elf_section_index_link, + Dwarf_Unsigned * relocation_buffer_count, + Dwarf_Relocation_Data * reldata_buffer, + Dwarf_Error * error) +{ + int next = dbg->de_reloc_next_to_return; + + if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) { + int i; + + for (i = next; i < NUM_DEBUG_SECTIONS; ++i) { + Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[i]; + + if (prel->pr_reloc_total_count > 0) { + dbg->de_reloc_next_to_return = i + 1; + + + /* ASSERT: prel->.pr_block_count == 1 */ + + *elf_section_index = prel->pr_sect_num_of_reloc_sect; + *elf_section_index_link = dbg->de_elf_sects[i]; + *relocation_buffer_count = prel->pr_reloc_total_count; + *reldata_buffer = (Dwarf_Relocation_Data) + (prel->pr_first_block->rb_data); + return DW_DLV_OK; + } + } + DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); + } + return DW_DLV_NO_ENTRY; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,47 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + + +int _dwarf_pro_pre_alloc_n_reloc_slots(Dwarf_P_Debug dbg, + int rel_sec_index, + Dwarf_Unsigned newslots); + +int _dwarf_pro_alloc_reloc_slots(Dwarf_P_Debug dbg, int rel_sec_index); + +int _dwarf_pro_reloc_get_a_slot(Dwarf_P_Debug dbg, + int base_sec_index, + void **relrec_to_fill); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_stream.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_stream.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,299 @@ +/* + + Copyright (C) 2000,2001,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#else +/* Set r_info as defined by ELF generic ABI */ +#define Set_REL32_info(r,s,t) ((r).r_info = ELF32_R_INFO(s,t)) +#define Set_REL64_info(r,s,t) ((r).r_info = ELF64_R_INFO(s,t)) +#endif +#include "pro_incl.h" +#include "pro_section.h" +#include "pro_reloc.h" +#include "pro_reloc_stream.h" + +/* + Return DW_DLV_ERROR on malloc error or reltarget_length error. + Return DW_DLV_OK otherwise + + + +*/ + /*ARGSUSED*/ int +_dwarf_pro_reloc_name_stream64(Dwarf_P_Debug dbg, + int base_sec_index, + Dwarf_Unsigned offset, /* r_offset of reloc */ + Dwarf_Unsigned symidx, + enum Dwarf_Rel_Type type, + int reltarget_length) +{ +#if HAVE_ELF64_GETEHDR + REL64 *elf64_reloc; + void *relrec_to_fill; + int res; + int rel_type; + + res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, + &relrec_to_fill); + if (res != DW_DLV_OK) + return res; + + + if (type == dwarf_drt_data_reloc) { + if (reltarget_length == dbg->de_offset_size) { + rel_type = dbg->de_offset_reloc; + } else if (reltarget_length == dbg->de_pointer_size) { + rel_type = dbg->de_ptr_reloc; + } else { + return DW_DLV_ERROR; + } + } else if (type == dwarf_drt_segment_rel) { + rel_type = dbg->de_exc_reloc; + } else { + /* We are in trouble: improper use of stream relocations. + Someone else will diagnose */ + rel_type = 0; + } + + elf64_reloc = (REL64 *)relrec_to_fill; + elf64_reloc->r_offset = offset; + Set_REL64_info(*elf64_reloc, symidx, rel_type); + return DW_DLV_OK; +#else /* !HAVE_ELF64_GETEHDR */ + return DW_DLV_ERROR; +#endif /* #if HAVE_ELF64_GETEHDR */ +} + +/* + Return DW_DLV_ERROR on malloc error or reltarget_length error. + Return DW_DLV_OK otherwise + a binary reloc: 32bit ABI +*/ +int +_dwarf_pro_reloc_name_stream32(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset + of + reloc + */ + Dwarf_Unsigned symidx, + enum Dwarf_Rel_Type type, + int reltarget_length) +{ + REL32 *elf32_reloc; + void *relrec_to_fill; + int res; + int rel_type; + + res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, + &relrec_to_fill); + if (res != DW_DLV_OK) + return res; + if (type == dwarf_drt_data_reloc) { + if (reltarget_length == dbg->de_offset_size) { + rel_type = dbg->de_offset_reloc; + } else if (reltarget_length == dbg->de_pointer_size) { + rel_type = dbg->de_ptr_reloc; + } else { + return DW_DLV_ERROR; + } + } else if (type == dwarf_drt_segment_rel) { + rel_type = dbg->de_exc_reloc; + } else { + /* We are in trouble: improper use of stream relocations. + Someone else will diagnose */ + rel_type = 0; + } + + elf32_reloc = (REL32*)relrec_to_fill; + elf32_reloc->r_offset = (Elf32_Addr) offset; + Set_REL32_info(*elf32_reloc, (Dwarf_Word) symidx, rel_type); + return DW_DLV_OK; + + /* get a slot, fill in the slot entry */ +} + + + +/* + Return DW_DLV_OK. + Never can really do anything: lengths cannot + be represented as end-start in a stream. + +*/ + /*ARGSUSED*/ int +_dwarf_pro_reloc_length_stream(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset + of + reloc + */ + Dwarf_Unsigned start_symidx, + Dwarf_Unsigned end_symidx, + enum Dwarf_Rel_Type type, + int reltarget_length) +{ + /* get a slot, fill in the slot entry */ + return DW_DLV_OK; +} + + +/* + Ensure each stream is a single buffer and + add that single buffer to the set of stream buffers. + + By creating a new buffer and copying if necessary. + + Free the input set of buffers if we consolidate. + Return -1 on error (malloc failure) + + + Return DW_DLV_OK on success. Any other return indicates + malloc failed. + +*/ +int +_dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg, + Dwarf_Signed * new_sec_count) +{ + unsigned long total_size = 0; + Dwarf_Small *data; + int sec_index; + unsigned long i; + Dwarf_Error err; + Dwarf_Error *error = &err; + + Dwarf_Signed sec_count = 0; + + Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[0]; + + for (i = 0; i < NUM_DEBUG_SECTIONS; ++i, ++p_reloc) { + unsigned long ct = p_reloc->pr_reloc_total_count; + unsigned len; + struct Dwarf_P_Relocation_Block_s *p_blk; + struct Dwarf_P_Relocation_Block_s *p_blk_last; + Dwarf_P_Per_Reloc_Sect prb; + + if (ct == 0) { + continue; + } + prb = &dbg->de_reloc_sect[i]; + len = dbg->de_relocation_record_size; + ++sec_count; + + total_size = ct * len; + sec_index = prb->pr_sect_num_of_reloc_sect; + if (sec_index == 0) { + /* call de_func or de_func_b, getting section number of + reloc sec */ + int rel_section_index; + Dwarf_Unsigned name_idx; + int int_name; + int err; + + if (dbg->de_func_b) { + rel_section_index = + dbg->de_func_b(_dwarf_rel_section_names[i], + /* size */ + dbg->de_relocation_record_size, + /* type */ SHT_REL, + /* flags */ 0, + /* link to symtab, which we cannot + know */ 0, + /* info == link to sec rels apply to + */ + dbg->de_elf_sects[i], + &name_idx, &err); + } else { + rel_section_index = + dbg->de_func(_dwarf_rel_section_names[i], + /* size */ + dbg->de_relocation_record_size, + /* type */ SHT_REL, + /* flags */ 0, + /* link to symtab, which we cannot + know */ 0, + /* info == link to sec rels apply to */ + dbg->de_elf_sects[i], &int_name, &err); + name_idx = int_name; + } + if (rel_section_index == -1) { + { + _dwarf_p_error(dbg, error, DW_DLE_ELF_SECT_ERR); + return (DW_DLV_ERROR); + } + + } + prb->pr_sect_num_of_reloc_sect = rel_section_index; + sec_index = rel_section_index; + } + GET_CHUNK(dbg, sec_index, data, total_size, &err); + p_blk = p_reloc->pr_first_block; + + /* following loop executes at least once. Effects the + consolidation to a single block or, if already a single + block, simply copies to the output buffer. And frees the + input block. The new block is in the de_debug_sects list. */ + while (p_blk) { + + unsigned long len = + p_blk->rb_where_to_add_next - p_blk->rb_data; + + memcpy(data, p_blk->rb_data, len); + + + data += len; + + p_blk_last = p_blk; + p_blk = p_blk->rb_next; + + _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last); + } + /* ASSERT: sum of len copied == total_size */ + + /* + We have copied the input, now drop the pointers to it. For + debugging, leave the other data untouched. */ + p_reloc->pr_first_block = 0; + p_reloc->pr_last_block = 0; + } + + *new_sec_count = sec_count; + return DW_DLV_OK; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_stream.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_stream.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,63 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + + +int _dwarf_pro_reloc_name_stream64(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset + of + reloc + */ + Dwarf_Unsigned symidx, + enum Dwarf_Rel_Type, + int reltarget_length); +int _dwarf_pro_reloc_name_stream32(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset + of + reloc + */ + Dwarf_Unsigned symidx, + enum Dwarf_Rel_Type, + int reltarget_length); +int _dwarf_pro_reloc_length_stream(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset + of + reloc + */ + Dwarf_Unsigned start_symidx, + Dwarf_Unsigned end_symidx, + enum Dwarf_Rel_Type, + int reltarget_length); + +int _dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg, + Dwarf_Signed * new_sec_count); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_symbolic.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_symbolic.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,299 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +/*#include */ +#include "pro_incl.h" +#include "pro_section.h" +#include "pro_reloc.h" +#include "pro_reloc_symbolic.h" + +/* + Return DW_DLV_ERROR on malloc error. + Return DW_DLV_OK otherwise +*/ + +int +_dwarf_pro_reloc_name_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset + of + reloc + */ + Dwarf_Unsigned symidx, + enum Dwarf_Rel_Type type, + int reltarget_length) +{ + /* get a slot, fill in the slot entry */ + void *relrec_to_fill; + int res; + struct Dwarf_Relocation_Data_s *slotp; + + res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, + &relrec_to_fill); + if (res != DW_DLV_OK) + return res; + + slotp = (struct Dwarf_Relocation_Data_s *) relrec_to_fill; + slotp->drd_type = type; + slotp->drd_length = reltarget_length; + slotp->drd_offset = offset; + slotp->drd_symbol_index = symidx; + return DW_DLV_OK; + +} + + + +/* + Return DW_DLV_ERROR on malloc error. + Return DW_DLV_OK otherwise +*/ +int +_dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset + of + reloc + */ + Dwarf_Unsigned start_symidx, + Dwarf_Unsigned end_symidx, + enum Dwarf_Rel_Type type, + int reltarget_length) +{ + /* get a slot, fill in the slot entry */ + void *relrec_to_fill; + int res; + struct Dwarf_Relocation_Data_s *slotp1; + struct Dwarf_Relocation_Data_s *slotp2; + + + + res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, + &relrec_to_fill); + if (res != DW_DLV_OK) + return res; + slotp1 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill; + res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, + &relrec_to_fill); + if (res != DW_DLV_OK) + return res; + slotp2 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill; + + /* ASSERT: type == dwarf_drt_first_of_length_type_pair */ + slotp1->drd_type = type; + slotp1->drd_length = reltarget_length; + slotp1->drd_offset = offset; + slotp1->drd_symbol_index = start_symidx; + + slotp2->drd_type = dwarf_drt_second_of_length_pair; + slotp2->drd_length = reltarget_length; + slotp2->drd_offset = offset; + slotp2->drd_symbol_index = end_symidx; + + return DW_DLV_OK; +} + +/* + Reset whatever fields of Dwarf_P_Per_Reloc_Sect_s + we must to allow adding a fresh new single + block easily (block consolidation use only). + +*/ +static void +_dwarf_reset_reloc_sect_info(struct Dwarf_P_Per_Reloc_Sect_s *pblk, + unsigned long ct) +{ + + + /* do not zero pr_sect_num_of_reloc_sect */ + + pblk->pr_reloc_total_count = 0; + pblk->pr_first_block = 0; + pblk->pr_last_block = 0; + pblk->pr_block_count = 0; + pblk->pr_slots_per_block_to_alloc = ct; +} + +/* + Ensure each stream is a single buffer and + add that single buffer to the set of stream buffers. + + By creating a new buffer and copying if necessary. + (If > 1 block, reduce to 1 block) + + Free the input set of buffers if we consolidate. + + We pass back *new_sec_count as zero because we + are not creating normal sections for a .o, but + symbolic relocations, separately counted. + + Return -1 on error (malloc failure) + + + Return DW_DLV_OK on success. Any other return indicates + malloc failed. +*/ +int +_dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg, + Dwarf_Signed * new_sec_count) +{ + /* unsigned long total_size =0; */ + Dwarf_Small *data; + int sec_index; + int res; + unsigned long i; + Dwarf_Error error; + + Dwarf_Signed sec_count = 0; + + Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[0]; + + for (i = 0; i < NUM_DEBUG_SECTIONS; ++i, ++p_reloc) { + + unsigned long ct = p_reloc->pr_reloc_total_count; + struct Dwarf_P_Relocation_Block_s *p_blk; + struct Dwarf_P_Relocation_Block_s *p_blk_last; + + /* int len */ + int err; + + + if (ct == 0) { + continue; + } + + /* len = dbg->de_relocation_record_size; */ + ++sec_count; + + /* total_size = ct *len; */ + sec_index = p_reloc->pr_sect_num_of_reloc_sect; + if (sec_index == 0) { + /* call de_func or de_func_b, getting section number of + reloc sec */ + int rel_section_index; + int int_name; + Dwarf_Unsigned name_idx; + + /* + This is a bit of a fake, as we do not really have true + elf sections at all. Just the data such might contain. + But this lets the caller eventually link things + together: without this call we would not know what rel + data goes with what section when we are asked for the + real arrays. */ + + if (dbg->de_func_b) { + rel_section_index = + dbg->de_func_b(_dwarf_rel_section_names[i], + dbg->de_relocation_record_size, + /* type */ SHT_REL, + /* flags */ 0, + /* link to symtab, which we cannot + know */ SHN_UNDEF, + /* sec rels apply to */ + dbg->de_elf_sects[i], + &name_idx, &err); + } else { + rel_section_index = + dbg->de_func(_dwarf_rel_section_names[i], + dbg->de_relocation_record_size, + /* type */ SHT_REL, + /* flags */ 0, + /* link to symtab, which we cannot + know */ SHN_UNDEF, + /* sec rels apply to, in elf, sh_info */ + dbg->de_elf_sects[i], &int_name, &err); + name_idx = int_name; + } + if (rel_section_index == -1) { + { + _dwarf_p_error(dbg, &error, DW_DLE_ELF_SECT_ERR); + return (DW_DLV_ERROR); + } + } + p_reloc->pr_sect_num_of_reloc_sect = rel_section_index; + sec_index = rel_section_index; + } + + p_blk = p_reloc->pr_first_block; + + if (p_reloc->pr_block_count > 1) { + struct Dwarf_P_Relocation_Block_s *new_blk; + + /* HACK , not normal interfaces, trashing p_reloc current + contents! */ + _dwarf_reset_reloc_sect_info(p_reloc, ct); + + /* Creating new single block for all 'ct' entries */ + res = _dwarf_pro_pre_alloc_n_reloc_slots(dbg, (int) i, ct); + + + if (res != DW_DLV_OK) { + return res; + } + new_blk = p_reloc->pr_first_block; + + data = (Dwarf_Small *) new_blk->rb_data; + + /* The following loop does the consolidation to a single + block and frees the input block(s). */ + do { + + unsigned long len = + p_blk->rb_where_to_add_next - p_blk->rb_data; + + memcpy(data, p_blk->rb_data, len); + data += len; + + p_blk_last = p_blk; + p_blk = p_blk->rb_next; + + _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last); + } while (p_blk); + /* ASSERT: sum of len copied == total_size */ + new_blk->rb_next_slot_to_use = ct; + new_blk->rb_where_to_add_next = (char *) data; + p_reloc->pr_reloc_total_count = ct; + + /* have now created a single block, but no change in slots + used (pr_reloc_total_count) */ + } + } + + *new_sec_count = 0; + return DW_DLV_OK; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_symbolic.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_symbolic.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,55 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + +int _dwarf_pro_reloc_name_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset + of + reloc + */ + Dwarf_Unsigned symidx, + enum Dwarf_Rel_Type, + int reltarget_length); +int + _dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset + of + reloc + */ + Dwarf_Unsigned start_symidx, + Dwarf_Unsigned end_symidx, + enum Dwarf_Rel_Type, + int reltarget_length); + +int _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg, + Dwarf_Signed * new_sec_count); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_section.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_section.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,2217 @@ +/* + + Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007 David Anderson. All Rights Reserved. + Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* + SGI has moved from the Crittenden Lane address. +*/ + + + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#endif +#include "pro_incl.h" +#include "pro_section.h" +#include "pro_line.h" +#include "pro_frame.h" +#include "pro_die.h" +#include "pro_macinfo.h" +#include "pro_types.h" + +#ifndef SHF_MIPS_NOSTRIP +/* if this is not defined, we probably don't need it: just use 0 */ +#define SHF_MIPS_NOSTRIP 0 +#endif +#ifndef R_MIPS_NONE +#define R_MIPS_NONE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +/* must match up with pro_section.h defines of DEBUG_INFO etc +and sectnames (below). REL_SEC_PREFIX is either ".rel" or ".rela" +see pro_incl.h +*/ +char *_dwarf_rel_section_names[] = { + REL_SEC_PREFIX ".debug_info", + REL_SEC_PREFIX ".debug_line", + REL_SEC_PREFIX ".debug_abbrev", /* no relocations on this, really */ + REL_SEC_PREFIX ".debug_frame", + REL_SEC_PREFIX ".debug_aranges", + REL_SEC_PREFIX ".debug_pubnames", + REL_SEC_PREFIX ".debug_str", + REL_SEC_PREFIX ".debug_funcnames", /* sgi extension */ + REL_SEC_PREFIX ".debug_typenames", /* sgi extension */ + REL_SEC_PREFIX ".debug_varnames", /* sgi extension */ + REL_SEC_PREFIX ".debug_weaknames", /* sgi extension */ + REL_SEC_PREFIX ".debug_macinfo", + REL_SEC_PREFIX ".debug_loc" +}; + +/* names of sections. Ensure that it matches the defines + in pro_section.h, in the same order + Must match also _dwarf_rel_section_names above +*/ +char *_dwarf_sectnames[] = { + ".debug_info", + ".debug_line", + ".debug_abbrev", + ".debug_frame", + ".debug_aranges", + ".debug_pubnames", + ".debug_str", + ".debug_funcnames", /* sgi extension */ + ".debug_typenames", /* sgi extension */ + ".debug_varnames", /* sgi extension */ + ".debug_weaknames", /* sgi extension */ + ".debug_macinfo", + ".debug_loc" +}; + + + + +static Dwarf_Ubyte std_opcode_len[] = { 0, /* DW_LNS_copy */ + 1, /* DW_LNS_advance_pc */ + 1, /* DW_LNS_advance_line */ + 1, /* DW_LNS_set_file */ + 1, /* DW_LNS_set_column */ + 0, /* DW_LNS_negate_stmt */ + 0, /* DW_LNS_set_basic_block */ + 0, /* DW_LNS_const_add_pc */ + 1, /* DW_LNS_fixed_advance_pc */ +}; + +/* struct to hold relocation entries. Its mantained as a linked + list of relocation structs, and will then be written at as a + whole into the relocation section. Whether its 32 bit or + 64 bit will be obtained from Dwarf_Debug pointer. +*/ + +typedef struct Dwarf_P_Rel_s *Dwarf_P_Rel; +struct Dwarf_P_Rel_s { + Dwarf_P_Rel dr_next; + void *dr_rel_datap; +}; +typedef struct Dwarf_P_Rel_Head_s *Dwarf_P_Rel_Head; +struct Dwarf_P_Rel_Head_s { + struct Dwarf_P_Rel_s *drh_head; + struct Dwarf_P_Rel_s *drh_tail; +}; + +static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, + Dwarf_Error * error); +static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, + Dwarf_Error * error); +static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, + Dwarf_Error * error); +static Dwarf_P_Abbrev _dwarf_pro_getabbrev(Dwarf_P_Die, Dwarf_P_Abbrev); +static int _dwarf_pro_match_attr + (Dwarf_P_Attribute, Dwarf_P_Abbrev, int no_attr); + +/* these macros used as return value for below functions */ +#define OPC_INCS_ZERO -1 +#define OPC_OUT_OF_RANGE -2 +#define LINE_OUT_OF_RANGE -3 +static int _dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv); + + +/* BEGIN_LEN_SIZE is the size of the 'length' field in total. + Which may be 4,8, or 12 bytes! + 4 is standard DWARF2. + 8 is non-standard MIPS-IRIX 64-bit. + 12 is standard DWARF3 for 64 bit offsets. + Used in various routines: local variable names + must match the names here. +*/ +#define BEGIN_LEN_SIZE (uwordb_size + extension_size) + +/* + Return TRUE if we need the section, FALSE otherwise + + If any of the 'line-data-related' calls were made + including file or directory entries, + produce .debug_line . + +*/ +static int +dwarf_need_debug_line_section(Dwarf_P_Debug dbg) +{ + if (dbg->de_lines == NULL && dbg->de_file_entries == NULL + && dbg->de_inc_dirs == NULL) { + return FALSE; + } + return TRUE; +} + +/* + Convert debug information to a format such that + it can be written on disk. + Called exactly once per execution. +*/ +Dwarf_Signed +dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + /* + Section data in written out in a number of buffers. Each + _generate_*() function returns a cumulative count of buffers for + all the sections. get_section_bytes() returns pointers to these + buffers one at a time. */ + int nbufs; + int sect; + int name_idx; + int err; + Dwarf_Unsigned du; + + if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_NOCOUNT); + } + + /* Create dwarf section headers */ + for (sect = 0; sect < NUM_DEBUG_SECTIONS; sect++) { + long flags = 0; + + switch (sect) { + + case DEBUG_INFO: + if (dbg->de_dies == NULL) + continue; + break; + + case DEBUG_LINE: + if (dwarf_need_debug_line_section(dbg) == FALSE) { + continue; + } + break; + + case DEBUG_ABBREV: + if (dbg->de_dies == NULL) + continue; + break; + + case DEBUG_FRAME: + if (dbg->de_frame_cies == NULL) + continue; + flags = SHF_MIPS_NOSTRIP; + break; + + case DEBUG_ARANGES: + if (dbg->de_arange == NULL) + continue; + break; + + case DEBUG_PUBNAMES: + if (dbg->de_simple_name_headers[dwarf_snk_pubname]. + sn_head == NULL) + continue; + break; + + case DEBUG_STR: + if (dbg->de_strings == NULL) + continue; + break; + + case DEBUG_FUNCNAMES: + if (dbg->de_simple_name_headers[dwarf_snk_funcname]. + sn_head == NULL) + continue; + break; + + case DEBUG_TYPENAMES: + if (dbg->de_simple_name_headers[dwarf_snk_typename]. + sn_head == NULL) + continue; + break; + + case DEBUG_VARNAMES: + if (dbg->de_simple_name_headers[dwarf_snk_varname]. + sn_head == NULL) + continue; + break; + + case DEBUG_WEAKNAMES: + if (dbg->de_simple_name_headers[dwarf_snk_weakname]. + sn_head == NULL) + continue; + break; + + case DEBUG_MACINFO: + if (dbg->de_first_macinfo == NULL) + continue; + break; + case DEBUG_LOC: + /* not handled yet */ + continue; + default: + /* logic error: missing a case */ + DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_NOCOUNT); + } + { + int new_base_elf_sect; + + if (dbg->de_func_b) { + new_base_elf_sect = + dbg->de_func_b(_dwarf_sectnames[sect], + /* rec size */ 1, + SECTION_TYPE, + flags, SHN_UNDEF, 0, &du, &err); + + } else { + new_base_elf_sect = dbg->de_func(_dwarf_sectnames[sect], + dbg-> + de_relocation_record_size, + SECTION_TYPE, flags, + SHN_UNDEF, 0, + &name_idx, &err); + du = name_idx; + } + if (new_base_elf_sect == -1) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, + DW_DLV_NOCOUNT); + } + dbg->de_elf_sects[sect] = new_base_elf_sect; + + dbg->de_sect_name_idx[sect] = du; + } + } + + nbufs = 0; + + /* + Changing the order in which the sections are generated may cause + problems because of relocations. */ + + if (dwarf_need_debug_line_section(dbg) == TRUE) { + nbufs = _dwarf_pro_generate_debugline(dbg, error); + if (nbufs < 0) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGLINE_ERROR, + DW_DLV_NOCOUNT); + } + } + + if (dbg->de_frame_cies) { + nbufs = _dwarf_pro_generate_debugframe(dbg, error); + if (nbufs < 0) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGFRAME_ERROR, + DW_DLV_NOCOUNT); + } + } + if (dbg->de_first_macinfo) { + nbufs = _dwarf_pro_transform_macro_info_to_disk(dbg, error); + if (nbufs < 0) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGMACINFO_ERROR, + DW_DLV_NOCOUNT); + } + } + + if (dbg->de_dies) { + nbufs = _dwarf_pro_generate_debuginfo(dbg, error); + if (nbufs < 0) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, + DW_DLV_NOCOUNT); + } + } + + if (dbg->de_arange) { + nbufs = _dwarf_transform_arange_to_disk(dbg, error); + if (nbufs < 0) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, + DW_DLV_NOCOUNT); + } + } + + if (dbg->de_simple_name_headers[dwarf_snk_pubname].sn_head) { + nbufs = _dwarf_transform_simplename_to_disk(dbg, + dwarf_snk_pubname, + DEBUG_PUBNAMES, + error); + + + if (nbufs < 0) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, + DW_DLV_NOCOUNT); + } + } + + if (dbg->de_simple_name_headers[dwarf_snk_funcname].sn_head) { + nbufs = _dwarf_transform_simplename_to_disk(dbg, + dwarf_snk_funcname, + DEBUG_FUNCNAMES, + error); + if (nbufs < 0) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, + DW_DLV_NOCOUNT); + } + } + + if (dbg->de_simple_name_headers[dwarf_snk_typename].sn_head) { + nbufs = _dwarf_transform_simplename_to_disk(dbg, + dwarf_snk_typename, + DEBUG_TYPENAMES, + error); + if (nbufs < 0) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, + DW_DLV_NOCOUNT); + } + } + + if (dbg->de_simple_name_headers[dwarf_snk_varname].sn_head) { + nbufs = _dwarf_transform_simplename_to_disk(dbg, + dwarf_snk_varname, + DEBUG_VARNAMES, + error); + + if (nbufs < 0) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, + DW_DLV_NOCOUNT); + } + } + + if (dbg->de_simple_name_headers[dwarf_snk_weakname].sn_head) { + nbufs = _dwarf_transform_simplename_to_disk(dbg, + dwarf_snk_weakname, + DEBUG_WEAKNAMES, + error); + + if (nbufs < 0) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, + DW_DLV_NOCOUNT); + } + } + + { + Dwarf_Signed new_secs; + int res; + + res = dbg->de_transform_relocs_to_disk(dbg, &new_secs); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, + DW_DLV_NOCOUNT); + } + nbufs += new_secs; + } + return nbufs; +} + + +/*--------------------------------------------------------------- + Generate debug_line section +---------------------------------------------------------------*/ +static int +_dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + Dwarf_P_Inc_Dir curdir = 0; + Dwarf_P_F_Entry curentry = 0; + Dwarf_P_Line curline = 0; + Dwarf_P_Line prevline = 0; + + /* all data named cur* are used to loop thru linked lists */ + + int sum_bytes = 0; + int prolog_size = 0; + unsigned char *data = 0; /* holds disk form data */ + int elfsectno = 0; + unsigned char *start_line_sec = 0; /* pointer to the buffer at + section start */ + /* temps for memcpy */ + Dwarf_Unsigned du = 0; + Dwarf_Ubyte db = 0; + Dwarf_Half dh = 0; + int res = 0; + int uwordb_size = dbg->de_offset_size; + int extension_size = dbg->de_64bit_extension ? 4 : 0; + int upointer_size = dbg->de_pointer_size; + char buff1[ENCODE_SPACE_NEEDED]; + + + + sum_bytes = 0; + + elfsectno = dbg->de_elf_sects[DEBUG_LINE]; + + /* include directories */ + curdir = dbg->de_inc_dirs; + while (curdir) { + prolog_size += strlen(curdir->did_name) + 1; + curdir = curdir->did_next; + } + prolog_size++; /* last null following last directory + entry. */ + + /* file entries */ + curentry = dbg->de_file_entries; + while (curentry) { + prolog_size += + strlen(curentry->dfe_name) + 1 + curentry->dfe_nbytes; + curentry = curentry->dfe_next; + } + prolog_size++; /* last null byte */ + + + prolog_size += BEGIN_LEN_SIZE + sizeof_uhalf(dbg) + /* version # */ + uwordb_size + /* header length */ + sizeof_ubyte(dbg) + /* min_instr length */ + sizeof_ubyte(dbg) + /* default is_stmt */ + sizeof_ubyte(dbg) + /* linebase */ + sizeof_ubyte(dbg) + /* linerange */ + sizeof_ubyte(dbg); /* opcode base */ + + /* length of table specifying # of opnds */ + prolog_size += sizeof(std_opcode_len); + + GET_CHUNK(dbg, elfsectno, data, prolog_size, error); + start_line_sec = data; + + /* copy over the data */ + /* total_length */ + du = 0; + if (extension_size) { + Dwarf_Word x = DISTINGUISHED_VALUE; + + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &x, + sizeof(x), extension_size); + data += extension_size; + } + + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, + sizeof(du), uwordb_size); + data += uwordb_size; + + dh = VERSION; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh, + sizeof(dh), sizeof(Dwarf_Half)); + data += sizeof(Dwarf_Half); + + /* header length */ + du = prolog_size - (BEGIN_LEN_SIZE + sizeof(Dwarf_Half) + + uwordb_size); + { + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, + sizeof(du), uwordb_size); + data += uwordb_size; + } + db = MIN_INST_LENGTH; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + db = DEFAULT_IS_STMT; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + db = (Dwarf_Ubyte) LINE_BASE; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + db = LINE_RANGE; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + db = OPCODE_BASE; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + WRITE_UNALIGNED(dbg, (void *) data, (const void *) std_opcode_len, + sizeof(std_opcode_len), sizeof(std_opcode_len)); + data += sizeof(std_opcode_len); + + /* copy over include directories */ + curdir = dbg->de_inc_dirs; + while (curdir) { + strcpy((char *) data, curdir->did_name); + data += strlen(curdir->did_name) + 1; + curdir = curdir->did_next; + } + *data = '\0'; /* last null */ + data++; + + /* copy file entries */ + curentry = dbg->de_file_entries; + while (curentry) { + strcpy((char *) data, curentry->dfe_name); + data += strlen(curentry->dfe_name) + 1; + /* copies of leb numbers, no endian issues */ + memcpy((void *) data, + (const void *) curentry->dfe_args, curentry->dfe_nbytes); + data += curentry->dfe_nbytes; + curentry = curentry->dfe_next; + } + *data = '\0'; + data++; + + sum_bytes += prolog_size; + + curline = dbg->de_lines; + prevline = (Dwarf_P_Line) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s)); + if (prevline == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, -1); + } + _dwarf_pro_reg_init(prevline); + /* generate opcodes for line numbers */ + while (curline) { + int nbytes; + char *arg; + int opc; + int no_lns_copy; /* if lns copy opcode doesnt need to be + generated, if special opcode or end + sequence */ + Dwarf_Unsigned addr_adv; + int line_adv; /* supposed to be a reasonably small + number, so the size should not be a + problem. ? */ + + no_lns_copy = 0; + if (curline->dpl_opc != 0) { + int inst_bytes; /* no of bytes in extended opcode */ + char *str; /* hold leb encoded inst_bytes */ + int str_nbytes; /* no of bytes in str */ + + switch (curline->dpl_opc) { + case DW_LNE_end_sequence: + + /* Advance pc to end of text section. */ + addr_adv = curline->dpl_address - prevline->dpl_address; + if (addr_adv > 0) { + db = DW_LNS_advance_pc; + res = + _dwarf_pro_encode_leb128_nm(addr_adv / + MIN_INST_LENGTH, + &nbytes, buff1, + sizeof(buff1)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + } + GET_CHUNK(dbg, elfsectno, data, + nbytes + sizeof(Dwarf_Ubyte), error); + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &db, sizeof(db), + sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + /* leb, no endianness issue */ + memcpy((void *) data, (const void *) buff1, nbytes); + data += nbytes + sizeof(Dwarf_Ubyte); + sum_bytes += nbytes + sizeof(Dwarf_Ubyte); + prevline->dpl_address = curline->dpl_address; + } + + /* first null byte */ + db = 0; + GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), + error); + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + sum_bytes += sizeof(Dwarf_Ubyte); + + /* write length of extended opcode */ + inst_bytes = sizeof(Dwarf_Ubyte); + res = + _dwarf_pro_encode_leb128_nm(inst_bytes, &str_nbytes, + buff1, sizeof(buff1)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + } + GET_CHUNK(dbg, elfsectno, data, str_nbytes, error); + memcpy((void *) data, (const void *) buff1, str_nbytes); + data += str_nbytes; + sum_bytes += str_nbytes; + + /* write extended opcode */ + db = DW_LNE_end_sequence; + GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), + error); + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + sum_bytes += sizeof(Dwarf_Ubyte); + /* reset value to original values */ + _dwarf_pro_reg_init(prevline); + no_lns_copy = 1; + /* this is set only for end_sequence, so that a + dw_lns_copy is not generated */ + break; + + case DW_LNE_set_address: + + /* first null byte */ + db = 0; + GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), + error); + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + sum_bytes += sizeof(Dwarf_Ubyte); + + /* write length of extended opcode */ + inst_bytes = sizeof(Dwarf_Ubyte) + upointer_size; + res = + _dwarf_pro_encode_leb128_nm(inst_bytes, &str_nbytes, + buff1, sizeof(buff1)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + } + GET_CHUNK(dbg, elfsectno, data, str_nbytes, error); + str = buff1; + /* leb number, no endian issue */ + memcpy((void *) data, (const void *) str, str_nbytes); + data += str_nbytes; + sum_bytes += str_nbytes; + + /* write extended opcode */ + db = DW_LNE_set_address; + GET_CHUNK(dbg, elfsectno, data, upointer_size + + sizeof(Dwarf_Ubyte), error); + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + sum_bytes += sizeof(Dwarf_Ubyte); + + /* reloc for address */ + res = dbg->de_reloc_name(dbg, DEBUG_LINE, sum_bytes, /* r_offset + */ + curline->dpl_r_symidx, + dwarf_drt_data_reloc, + uwordb_size); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + } + + /* write offset (address) */ + du = curline->dpl_address; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, + sizeof(du), upointer_size); + data += upointer_size; + sum_bytes += upointer_size; + prevline->dpl_address = curline->dpl_address; + no_lns_copy = 1; + break; + } + } else { + if (curline->dpl_file != prevline->dpl_file) { + db = DW_LNS_set_file; + res = + _dwarf_pro_encode_leb128_nm(curline->dpl_file, + &nbytes, buff1, + sizeof(buff1)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + } + arg = buff1; + GET_CHUNK(dbg, elfsectno, data, + nbytes + sizeof(Dwarf_Ubyte), error); + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + memcpy((void *) data, (const void *) arg, nbytes); + data += nbytes; + sum_bytes += nbytes + sizeof(Dwarf_Ubyte); + prevline->dpl_file = curline->dpl_file; + } + if (curline->dpl_column != prevline->dpl_column) { + db = DW_LNS_set_column; + res = _dwarf_pro_encode_leb128_nm(curline->dpl_column, + &nbytes, + buff1, sizeof(buff1)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + } + + arg = buff1; + GET_CHUNK(dbg, elfsectno, data, + nbytes + sizeof(Dwarf_Ubyte), error); + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + memcpy((void *) data, (const void *) arg, nbytes); + data += nbytes; + sum_bytes += nbytes + sizeof(Dwarf_Ubyte); + prevline->dpl_column = curline->dpl_column; + } + if (curline->dpl_is_stmt != prevline->dpl_is_stmt) { + db = DW_LNS_negate_stmt; + GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), + error); + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + sum_bytes += sizeof(Dwarf_Ubyte); + prevline->dpl_is_stmt = curline->dpl_is_stmt; + } + if (curline->dpl_basic_block == true && + prevline->dpl_basic_block == false) { + db = DW_LNS_set_basic_block; + GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), + error); + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + sum_bytes += sizeof(Dwarf_Ubyte); + prevline->dpl_basic_block = curline->dpl_basic_block; + } + addr_adv = curline->dpl_address - prevline->dpl_address; + + line_adv = (int) (curline->dpl_line - prevline->dpl_line); + if ((addr_adv % MIN_INST_LENGTH) != 0) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_ADDRESS, -1); + } + if ((opc = _dwarf_pro_get_opc(addr_adv, line_adv)) > 0) { + no_lns_copy = 1; + db = opc; + GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), + error); + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + sum_bytes += sizeof(Dwarf_Ubyte); + prevline->dpl_basic_block = false; + prevline->dpl_address = curline->dpl_address; + prevline->dpl_line = curline->dpl_line; + } else { + if (addr_adv > 0) { + db = DW_LNS_advance_pc; + res = + _dwarf_pro_encode_leb128_nm(addr_adv / + MIN_INST_LENGTH, + &nbytes, buff1, + sizeof(buff1)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + } + + arg = buff1; + GET_CHUNK(dbg, elfsectno, data, + nbytes + sizeof(Dwarf_Ubyte), error); + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + memcpy((void *) data, (const void *) arg, nbytes); + data += nbytes + sizeof(Dwarf_Ubyte); + sum_bytes += nbytes + sizeof(Dwarf_Ubyte); + prevline->dpl_basic_block = false; + prevline->dpl_address = curline->dpl_address; + } + if (line_adv != 0) { + db = DW_LNS_advance_line; + res = _dwarf_pro_encode_signed_leb128_nm(line_adv, + &nbytes, + buff1, + sizeof + (buff1)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + } + + arg = buff1; + GET_CHUNK(dbg, elfsectno, data, + nbytes + sizeof(Dwarf_Ubyte), error); + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &db, sizeof(db), + sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + memcpy((void *) data, (const void *) arg, nbytes); + data += nbytes + sizeof(Dwarf_Ubyte); + sum_bytes += nbytes + sizeof(Dwarf_Ubyte); + prevline->dpl_basic_block = false; + prevline->dpl_line = curline->dpl_line; + } + } + } /* ends else for opc != 0 */ + if (no_lns_copy == 0) { /* if not a special or dw_lne_end_seq + generate a matrix line */ + db = DW_LNS_copy; + GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), error); + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + sum_bytes += sizeof(Dwarf_Ubyte); + prevline->dpl_basic_block = false; + } + curline = curline->dpl_next; + } + + /* write total length field */ + du = sum_bytes - BEGIN_LEN_SIZE; + { + start_line_sec += extension_size; + WRITE_UNALIGNED(dbg, (void *) start_line_sec, + (const void *) &du, sizeof(du), uwordb_size); + } + + return (int) dbg->de_n_debug_sect; +} + +/*--------------------------------------------------------------- + Generate debug_frame section +---------------------------------------------------------------*/ +static int +_dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + int elfsectno; + int i; + int firsttime = 1; + int pad; /* pad for padding to align cies and + fdes */ + Dwarf_P_Cie curcie; + Dwarf_P_Fde curfde; + unsigned char *data; + Dwarf_sfixed dsw; + Dwarf_Unsigned du; + Dwarf_Ubyte db; + long *cie_offs; /* holds byte offsets for links to + fde's */ + unsigned long cie_length; + int cie_no; + int uwordb_size = dbg->de_offset_size; + int extension_size = dbg->de_64bit_extension ? 4 : 0; + int upointer_size = dbg->de_pointer_size; + Dwarf_Unsigned cur_off; /* current offset of written data, held + for relocation info */ + + elfsectno = dbg->de_elf_sects[DEBUG_FRAME]; + + curcie = dbg->de_frame_cies; + cie_length = 0; + cur_off = 0; + cie_offs = (long *) + _dwarf_p_get_alloc(dbg, sizeof(long) * dbg->de_n_cie); + if (cie_offs == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); + } + /* generate cie number as we go along */ + cie_no = 1; + while (curcie) { + char *code_al; + int c_bytes; + char *data_al; + int d_bytes; + int res; + char buff1[ENCODE_SPACE_NEEDED]; + char buff2[ENCODE_SPACE_NEEDED]; + char buff3[ENCODE_SPACE_NEEDED]; + char *augmentation; + char *augmented_al; + long augmented_fields_length; + int a_bytes; + + res = _dwarf_pro_encode_leb128_nm(curcie->cie_code_align, + &c_bytes, + buff1, sizeof(buff1)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); + } + /* Before April 1999, the following was using an unsigned + encode. That worked ok even though the decoder used the + correct signed leb read, but doing the encode correctly + (according to the dwarf spec) saves space in the output file + and is completely compatible. + + Note the actual stored amount on MIPS was 10 bytes (!) to + store the value -4. (hex)fc ffffffff ffffffff 01 The + libdwarf consumer consumed all 10 bytes too! + + old version res = + _dwarf_pro_encode_leb128_nm(curcie->cie_data_align, + + below is corrected signed version. */ + res = _dwarf_pro_encode_signed_leb128_nm(curcie->cie_data_align, + &d_bytes, + buff2, sizeof(buff2)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); + } + code_al = buff1; + data_al = buff2; + + /* get the correct offset */ + if (firsttime) { + cie_offs[cie_no - 1] = 0; + firsttime = 0; + } else { + cie_offs[cie_no - 1] = cie_offs[cie_no - 2] + + (long) cie_length + BEGIN_LEN_SIZE; + } + cie_no++; + augmentation = curcie->cie_aug; + if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) { + augmented_fields_length = 0; + res = _dwarf_pro_encode_leb128_nm(augmented_fields_length, + &a_bytes, buff3, + sizeof(buff3)); + augmented_al = buff3; + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); + } + cie_length = uwordb_size + /* cie_id */ + sizeof(Dwarf_Ubyte) + /* cie version */ + strlen(curcie->cie_aug) + 1 + /* augmentation */ + c_bytes + /* code alignment factor */ + d_bytes + /* data alignment factor */ + sizeof(Dwarf_Ubyte) + /* return reg address */ + a_bytes + /* augmentation length */ + curcie->cie_inst_bytes; + } else { + cie_length = uwordb_size + /* cie_id */ + sizeof(Dwarf_Ubyte) + /* cie version */ + strlen(curcie->cie_aug) + 1 + /* augmentation */ + c_bytes + d_bytes + sizeof(Dwarf_Ubyte) + /* return + reg + address + */ + curcie->cie_inst_bytes; + } + pad = (int) PADDING(cie_length, upointer_size); + cie_length += pad; + GET_CHUNK(dbg, elfsectno, data, cie_length + + BEGIN_LEN_SIZE, error); + if (extension_size) { + Dwarf_Unsigned x = DISTINGUISHED_VALUE; + + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &x, + sizeof(x), extension_size); + data += extension_size; + + } + du = cie_length; + /* total length of cie */ + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &du, sizeof(du), uwordb_size); + data += uwordb_size; + + /* cie-id is a special value. */ + du = DW_CIE_ID; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, + sizeof(du), uwordb_size); + data += uwordb_size; + + db = curcie->cie_version; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + strcpy((char *) data, curcie->cie_aug); + data += strlen(curcie->cie_aug) + 1; + memcpy((void *) data, (const void *) code_al, c_bytes); + data += c_bytes; + memcpy((void *) data, (const void *) data_al, d_bytes); + data += d_bytes; + db = curcie->cie_ret_reg; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + + if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) { + memcpy((void *) data, (const void *) augmented_al, a_bytes); + data += a_bytes; + } + memcpy((void *) data, (const void *) curcie->cie_inst, + curcie->cie_inst_bytes); + data += curcie->cie_inst_bytes; + for (i = 0; i < pad; i++) { + *data = DW_CFA_nop; + data++; + } + curcie = curcie->cie_next; + } + /* calculate current offset */ + cur_off = cie_offs[cie_no - 2] + cie_length + BEGIN_LEN_SIZE; + + /* write out fde's */ + curfde = dbg->de_frame_fdes; + while (curfde) { + Dwarf_P_Frame_Pgm curinst; + long fde_length; + int pad; + Dwarf_P_Cie cie_ptr; + Dwarf_Word cie_index, index; + int oet_length, afl_length, res; + int v0_augmentation = 0; + +#if 0 + unsigned char *fde_start_point; +#endif + + char afl_buff[ENCODE_SPACE_NEEDED]; + + /* Find the CIE associated with this fde. */ + cie_ptr = dbg->de_frame_cies; + cie_index = curfde->fde_cie; + index = 1; /* The cie_index of the first cie is 1, + not 0. */ + while (cie_ptr && index < cie_index) { + cie_ptr = cie_ptr->cie_next; + index++; + } + if (cie_ptr == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_NULL, -1); + } + + if (strcmp(cie_ptr->cie_aug, DW_CIE_AUGMENTER_STRING_V0) == 0) { + v0_augmentation = 1; + oet_length = sizeof(Dwarf_sfixed); + /* encode the length of augmented fields. */ + res = _dwarf_pro_encode_leb128_nm(oet_length, + &afl_length, afl_buff, + sizeof(afl_buff)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); + } + + fde_length = curfde->fde_n_bytes + BEGIN_LEN_SIZE + /* cie + pointer + */ + upointer_size + /* initial loc */ + upointer_size + /* address range */ + afl_length + /* augmented field length */ + oet_length; /* exception_table offset */ + } else { + fde_length = curfde->fde_n_bytes + BEGIN_LEN_SIZE + /* cie + pointer + */ + upointer_size + /* initial loc */ + upointer_size; /* address range */ + } + + /* using fde offset, generate DW_AT_MIPS_fde attribute for the + die corresponding to this fde */ + if (_dwarf_pro_add_AT_fde(dbg, curfde->fde_die, cur_off, error) + < 0) + return -1; + + /* store relocation for cie pointer */ + res = dbg->de_reloc_name(dbg, DEBUG_FRAME, cur_off + + BEGIN_LEN_SIZE, + /* r_offset */ + dbg->de_sect_name_idx[DEBUG_FRAME], + dwarf_drt_data_reloc, uwordb_size); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + } + + /* store relocation information for initial location */ + res = dbg->de_reloc_name(dbg, DEBUG_FRAME, + cur_off + BEGIN_LEN_SIZE + + upointer_size, + /* r_offset */ + curfde->fde_r_symidx, + dwarf_drt_data_reloc, upointer_size); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + } + /* Store the relocation information for the + offset_into_exception_info field, if the offset is valid (0 + is a valid offset). */ + if (v0_augmentation && + curfde->fde_offset_into_exception_tables >= 0) { + + res = dbg->de_reloc_name(dbg, DEBUG_FRAME, + /* r_offset, where in cie this + field starts */ + cur_off + BEGIN_LEN_SIZE + + uwordb_size + 2 * upointer_size + + afl_length, + curfde->fde_exception_table_symbol, + dwarf_drt_segment_rel, + sizeof(Dwarf_sfixed)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + } + } + + /* adjust for padding */ + pad = (int) PADDING(fde_length, upointer_size); + fde_length += pad; + + + /* write out fde */ + GET_CHUNK(dbg, elfsectno, data, fde_length + BEGIN_LEN_SIZE, + error); +#if 0 + fde_start_point = data; +#endif + du = fde_length; + { + if (extension_size) { + Dwarf_Word x = DISTINGUISHED_VALUE; + + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &x, + sizeof(x), extension_size); + data += extension_size; + } + /* length */ + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &du, + sizeof(du), uwordb_size); + data += uwordb_size; + + /* offset to cie */ + du = cie_offs[curfde->fde_cie - 1]; + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &du, + sizeof(du), uwordb_size); + data += uwordb_size; + + du = curfde->fde_initloc; + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &du, + sizeof(du), upointer_size); + data += upointer_size; + + if (dbg->de_reloc_pair && + curfde->fde_end_symbol != 0 && + curfde->fde_addr_range == 0) { + /* symbolic reloc, need reloc for length What if we + really know the length? If so, should use the other + part of 'if'. */ + Dwarf_Unsigned val; + + res = dbg->de_reloc_pair(dbg, + /* DEBUG_ARANGES, */ + DEBUG_FRAME, cur_off + 2 * uwordb_size + upointer_size, /* r_offset + */ + curfde->fde_r_symidx, + curfde->fde_end_symbol, + dwarf_drt_first_of_length_pair, + upointer_size); + if (res != DW_DLV_OK) { + { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (0); + } + } + + /* arrange pre-calc so assem text can do .word end - + begin + val (gets val from stream) */ + val = curfde->fde_end_symbol_offset - + curfde->fde_initloc; + WRITE_UNALIGNED(dbg, data, + (const void *) &val, + sizeof(val), upointer_size); + data += upointer_size; + } else { + + du = curfde->fde_addr_range; + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &du, + sizeof(du), upointer_size); + data += upointer_size; + } + } + + if (v0_augmentation) { + /* write the encoded augmented field length. */ + memcpy((void *) data, (const void *) afl_buff, afl_length); + data += afl_length; + /* write the offset_into_exception_tables field. */ + dsw = + (Dwarf_sfixed) curfde->fde_offset_into_exception_tables; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dsw, + sizeof(dsw), sizeof(Dwarf_sfixed)); + data += sizeof(Dwarf_sfixed); + } + + curinst = curfde->fde_inst; + while (curinst) { + db = curinst->dfp_opcode; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); +#if 0 + if (curinst->dfp_sym_index) { + int res; + + res = dbg->de_reloc_name(dbg, + DEBUG_FRAME, + (data - fde_start_point) + + cur_off + uwordb_size, /* r_offset + */ + curinst->dfp_sym_index, + dwarf_drt_data_reloc, + upointer_size); + if (res != DW_DLV_OK) { + { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (0); + } + } + } +#endif + memcpy((void *) data, + (const void *) curinst->dfp_args, + curinst->dfp_nbytes); + data += curinst->dfp_nbytes; + curinst = curinst->dfp_next; + } + /* padding */ + for (i = 0; i < pad; i++) { + *data = DW_CFA_nop; + data++; + } + cur_off += fde_length + uwordb_size; + curfde = curfde->fde_next; + } + + + return (int) dbg->de_n_debug_sect; +} + +/* + These functions remember all the markers we see along + with the right offset in the .debug_info section so that + we can dump them all back to the user with the section info. +*/ + +static int +marker_init(Dwarf_P_Debug dbg, + unsigned count) +{ + dbg->de_marker_n_alloc = count; + dbg->de_markers = NULL; + if (count > 0) { + dbg->de_markers = _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Marker_s) * + dbg->de_marker_n_alloc); + if (dbg->de_markers == NULL) { + dbg->de_marker_n_alloc = 0; + return -1; + } + } + return 0; +} + +static int +marker_add(Dwarf_P_Debug dbg, + Dwarf_Unsigned offset, + Dwarf_Unsigned marker) +{ + if (dbg->de_marker_n_alloc >= (dbg->de_marker_n_used + 1)) { + unsigned n = dbg->de_marker_n_used++; + dbg->de_markers[n].ma_offset = offset; + dbg->de_markers[n].ma_marker = marker; + return 0; + } + + return -1; +} + +Dwarf_Signed +dwarf_get_die_markers(Dwarf_P_Debug dbg, + Dwarf_P_Marker * marker_list, /* pointer to a pointer */ + Dwarf_Unsigned * marker_count, + Dwarf_Error * error) +{ + if (marker_list == NULL || marker_count == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_BADADDR); + } + if (dbg->de_marker_n_used != dbg->de_marker_n_alloc) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_BADADDR); + } + + *marker_list = dbg->de_markers; + *marker_count = dbg->de_marker_n_used; + return DW_DLV_OK; +} + +/* These functions provide the offsets of DW_FORM_string + attributes in the section section_index. These information + will enable a producer app that is generating assembly + text output to easily emit those attributes in ascii form + without having to decode the byte stream. + */ +static int +string_attr_init (Dwarf_P_Debug dbg, + Dwarf_Signed section_index, + unsigned count) +{ + Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index]; + + sect_sa->sect_sa_n_alloc = count; + sect_sa->sect_sa_list = NULL; + if (count > 0) { + sect_sa->sect_sa_section_number = section_index; + sect_sa->sect_sa_list = _dwarf_p_get_alloc(dbg, + sizeof(struct Dwarf_P_String_Attr_s) + * sect_sa->sect_sa_n_alloc); + if (sect_sa->sect_sa_list == NULL) { + sect_sa->sect_sa_n_alloc = 0; + return -1; + } + } + return 0; +} + +static int +string_attr_add (Dwarf_P_Debug dbg, + Dwarf_Signed section_index, + Dwarf_Unsigned offset, + Dwarf_P_Attribute attr) +{ + Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index]; + if (sect_sa->sect_sa_n_alloc >= (sect_sa->sect_sa_n_used + 1)) { + unsigned n = sect_sa->sect_sa_n_used++; + sect_sa->sect_sa_list[n].sa_offset = offset; + sect_sa->sect_sa_list[n].sa_nbytes = attr->ar_nbytes; + return 0; + } + + return -1; +} + +int +dwarf_get_string_attributes_count(Dwarf_P_Debug dbg, + Dwarf_Unsigned * + count_of_sa_sections, + int *drd_buffer_version, + Dwarf_Error *error) +{ + int i; + unsigned int count = 0; + + for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) { + if (dbg->de_sect_string_attr[i].sect_sa_n_used > 0) { + ++count; + } + } + *count_of_sa_sections = (Dwarf_Unsigned) count; + *drd_buffer_version = DWARF_DRD_BUFFER_VERSION; + + return DW_DLV_OK; +} + +int +dwarf_get_string_attributes_info(Dwarf_P_Debug dbg, + Dwarf_Signed *elf_section_index, + Dwarf_Unsigned *sect_sa_buffer_count, + Dwarf_P_String_Attr *sect_sa_buffer, + Dwarf_Error *error) +{ + int i; + int next = dbg->de_sect_sa_next_to_return; + + for (i = next; i < NUM_DEBUG_SECTIONS; ++i) { + Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[i]; + if (sect_sa->sect_sa_n_used > 0) { + dbg->de_sect_sa_next_to_return = i + 1; + *elf_section_index = sect_sa->sect_sa_section_number; + *sect_sa_buffer_count = sect_sa->sect_sa_n_used; + *sect_sa_buffer = sect_sa->sect_sa_list; + return DW_DLV_OK; + } + } + return DW_DLV_NO_ENTRY; +} + + + +/*--------------------------------------------------------------- + Generate debug_info and debug_abbrev sections +---------------------------------------------------------------*/ +static int +_dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + int elfsectno_of_debug_info = 0; + int abbrevsectno = 0; + unsigned char *data = 0; + int cu_header_size = 0; + Dwarf_P_Abbrev curabbrev = 0; + Dwarf_P_Abbrev abbrev_head = 0; + Dwarf_P_Abbrev abbrev_tail = 0; + Dwarf_P_Die curdie = 0; + Dwarf_P_Die first_child = 0; + Dwarf_Word dw = 0; + Dwarf_Unsigned du = 0; + Dwarf_Half dh = 0; + Dwarf_Ubyte db = 0; + Dwarf_Half version = 0; /* Need 2 byte quantity. */ + Dwarf_Unsigned die_off = 0; /* Offset of die in debug_info. */ + int n_abbrevs = 0; + int res = 0; + unsigned marker_count = 0; + unsigned string_attr_count = 0; + unsigned string_attr_offset = 0; + + Dwarf_Small *start_info_sec = 0; + + int uwordb_size = dbg->de_offset_size; + int extension_size = dbg->de_64bit_extension ? 4 : 0; + + abbrev_head = abbrev_tail = NULL; + elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO]; + + /* write cu header */ + cu_header_size = BEGIN_LEN_SIZE + sizeof(Dwarf_Half) + /* version + stamp + */ + uwordb_size + /* offset into abbrev table */ + sizeof(Dwarf_Ubyte); /* size of target address */ + GET_CHUNK(dbg, elfsectno_of_debug_info, data, cu_header_size, + error); + start_info_sec = data; + if (extension_size) { + du = DISTINGUISHED_VALUE; + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &du, sizeof(du), extension_size); + data += extension_size; + } + du = 0; /* length of debug_info, not counting + this field itself (unknown at this + point). */ + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &du, sizeof(du), uwordb_size); + data += uwordb_size; + + version = CURRENT_VERSION_STAMP; /* assume this length will not + change */ + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &version, + sizeof(version), sizeof(Dwarf_Half)); + data += sizeof(Dwarf_Half); + + du = 0; /* offset into abbrev table, not yet + known. */ + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &du, sizeof(du), uwordb_size); + data += uwordb_size; + + + db = dbg->de_pointer_size; + + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), 1); + + /* We have filled the chunk we got with GET_CHUNK. At this point we + no longer dare use "data" or "start_info_sec" as a pointer any + longer except to refer to that first small chunk for the cu + header. */ + + curdie = dbg->de_dies; + + /* create AT_macro_info if appropriate */ + if (dbg->de_first_macinfo != NULL) { + if (_dwarf_pro_add_AT_macro_info(dbg, curdie, 0, error) < 0) + return -1; + } + + /* create AT_stmt_list attribute if necessary */ + if (dwarf_need_debug_line_section(dbg) == TRUE) + if (_dwarf_pro_add_AT_stmt_list(dbg, curdie, error) < 0) + return -1; + + die_off = cu_header_size; + + /* + Relocation for abbrev offset in cu header store relocation + record in linked list */ + res = dbg->de_reloc_name(dbg, DEBUG_INFO, BEGIN_LEN_SIZE + + sizeof(Dwarf_Half), + /* r_offset */ + dbg->de_sect_name_idx[DEBUG_ABBREV], + dwarf_drt_data_reloc, uwordb_size); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); + } + + /* pass 0: only top level dies, add at_sibling attribute to those + dies with children */ + first_child = curdie->di_child; + while (first_child && first_child->di_right) { + if (first_child->di_child) + dwarf_add_AT_reference(dbg, + first_child, + DW_AT_sibling, + first_child->di_right, error); + first_child = first_child->di_right; + } + + /* pass 1: create abbrev info, get die offsets, calc relocations */ + marker_count = 0; + string_attr_count = 0; + while (curdie != NULL) { + int nbytes = 0; + Dwarf_P_Attribute curattr; + Dwarf_P_Attribute new_first_attr; + Dwarf_P_Attribute new_last_attr; + char *space = 0; + int res = 0; + char buff1[ENCODE_SPACE_NEEDED]; + int i = 0; + + curdie->di_offset = die_off; + + if (curdie->di_marker != 0) + marker_count++; + + curabbrev = _dwarf_pro_getabbrev(curdie, abbrev_head); + if (curabbrev == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); + } + if (abbrev_head == NULL) { + n_abbrevs = 1; + curabbrev->abb_idx = n_abbrevs; + abbrev_tail = abbrev_head = curabbrev; + } else { + /* check if its a new abbreviation, if yes, add to tail */ + if (curabbrev->abb_idx == 0) { + n_abbrevs++; + curabbrev->abb_idx = n_abbrevs; + abbrev_tail->abb_next = curabbrev; + abbrev_tail = curabbrev; + } + } + res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx, + &nbytes, + buff1, sizeof(buff1)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); + } + space = _dwarf_p_get_alloc(dbg, nbytes); + if (space == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); + } + memcpy(space, buff1, nbytes); + curdie->di_abbrev = space; + curdie->di_abbrev_nbytes = nbytes; + die_off += nbytes; + + /* Resorting the attributes!! */ + new_first_attr = new_last_attr = NULL; + curattr = curdie->di_attrs; + for (i = 0; i < (int)curabbrev->abb_n_attr; i++) { + Dwarf_P_Attribute ca; + Dwarf_P_Attribute cl; + + /* The following should always find an attribute! */ + for (ca = cl = curattr; + ca && curabbrev->abb_attrs[i] != ca->ar_attribute; + cl = ca, ca = ca->ar_next) + { + } + + if (!ca) { + DWARF_P_DBG_ERROR(dbg,DW_DLE_ABBREV_ALLOC, -1); + } + + /* Remove the attribute from the old list. */ + if (ca == curattr) { + curattr = ca->ar_next; + } else { + cl->ar_next = ca->ar_next; + } + + ca->ar_next = NULL; + + /* Add the attribute to the new list. */ + if (new_first_attr == NULL) { + new_first_attr = new_last_attr = ca; + } else { + new_last_attr->ar_next = ca; + new_last_attr = ca; + } + } + + curdie->di_attrs = new_first_attr; + + curattr = curdie->di_attrs; + + while (curattr) { + if (curattr->ar_rel_type != R_MIPS_NONE) { + switch (curattr->ar_attribute) { + case DW_AT_stmt_list: + curattr->ar_rel_symidx = + dbg->de_sect_name_idx[DEBUG_LINE]; + break; + case DW_AT_MIPS_fde: + curattr->ar_rel_symidx = + dbg->de_sect_name_idx[DEBUG_FRAME]; + break; + case DW_AT_macro_info: + curattr->ar_rel_symidx = + dbg->de_sect_name_idx[DEBUG_MACINFO]; + break; + default: + break; + } + res = dbg->de_reloc_name(dbg, DEBUG_INFO, die_off + curattr->ar_rel_offset, /* r_offset + */ + curattr->ar_rel_symidx, + dwarf_drt_data_reloc, + curattr->ar_reloc_len); + + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); + } + + } + if (curattr->ar_attribute_form == DW_FORM_string) { + string_attr_count++; + } + die_off += curattr->ar_nbytes; + curattr = curattr->ar_next; + } + + /* depth first search */ + if (curdie->di_child) + curdie = curdie->di_child; + else { + while (curdie != NULL && curdie->di_right == NULL) { + curdie = curdie->di_parent; + die_off++; /* since we are writing a null die at + the end of each sibling chain */ + } + if (curdie != NULL) + curdie = curdie->di_right; + } + + } /* end while (curdie != NULL) */ + + res = marker_init(dbg, marker_count); + if (res == -1) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); + } + res = string_attr_init(dbg, DEBUG_INFO, string_attr_count); + if (res == -1) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); + } + + /* Pass 2: Write out the die information Here 'data' is a + temporary, one block for each GET_CHUNK. 'data' is overused. */ + curdie = dbg->de_dies; + while (curdie != NULL) { + Dwarf_P_Attribute curattr; + + if (curdie->di_marker != 0) { + res = marker_add(dbg, curdie->di_offset, curdie->di_marker); + if (res == -1) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); + } + } + + /* index to abbreviation table */ + GET_CHUNK(dbg, elfsectno_of_debug_info, + data, curdie->di_abbrev_nbytes, error); + + memcpy((void *) data, + (const void *) curdie->di_abbrev, + curdie->di_abbrev_nbytes); + + /* Attribute values - need to fill in all form attributes */ + curattr = curdie->di_attrs; + string_attr_offset = curdie->di_offset + curdie->di_abbrev_nbytes; + + while (curattr) { + GET_CHUNK(dbg, elfsectno_of_debug_info, data, + (unsigned long) curattr->ar_nbytes, error); + switch (curattr->ar_attribute_form) { + case DW_FORM_ref1: + { + if (curattr->ar_ref_die->di_offset > + (unsigned) 0xff) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1); + } + db = curattr->ar_ref_die->di_offset; + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + break; + } + case DW_FORM_ref2: + { + if (curattr->ar_ref_die->di_offset > + (unsigned) 0xffff) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1); + } + dh = curattr->ar_ref_die->di_offset; + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &dh, + sizeof(dh), sizeof(Dwarf_Half)); + break; + } + case DW_FORM_ref_addr: + { + /* curattr->ar_ref_die == NULL! + * + * ref_addr doesn't take a CU-offset. + * This is different than other refs. + * This value will be set by the user of the + * producer library using a relocation. + * No need to set a value here. + */ +#if 0 + du = curattr->ar_ref_die->di_offset; + { + /* ref to offset of die */ + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &du, + sizeof(du), uwordb_size); + } +#endif + break; + + } + case DW_FORM_ref4: + { + if (curattr->ar_ref_die->di_offset > + (unsigned) 0xffffffff) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1); + } + dw = (Dwarf_Word) curattr->ar_ref_die->di_offset; + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &dw, + sizeof(dw), sizeof(Dwarf_ufixed)); + break; + } + case DW_FORM_ref8: + du = curattr->ar_ref_die->di_offset; + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &du, + sizeof(du), sizeof(Dwarf_Unsigned)); + break; + case DW_FORM_ref_udata: + { /* unsigned leb128 offset */ + + int nbytes; + char buff1[ENCODE_SPACE_NEEDED]; + + res = + _dwarf_pro_encode_leb128_nm(curattr-> + ar_ref_die-> + di_offset, &nbytes, + buff1, + sizeof(buff1)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); + } + + memcpy(data, buff1, nbytes); + break; + } + default: + memcpy((void *) data, + (const void *) curattr->ar_data, + curattr->ar_nbytes); + break; + } + if (curattr->ar_attribute_form == DW_FORM_string) { + string_attr_add(dbg, DEBUG_INFO, string_attr_offset, curattr); + } + string_attr_offset += curattr->ar_nbytes; + curattr = curattr->ar_next; + } + + /* depth first search */ + if (curdie->di_child) + curdie = curdie->di_child; + else { + while (curdie != NULL && curdie->di_right == NULL) { + GET_CHUNK(dbg, elfsectno_of_debug_info, data, 1, error); + *data = '\0'; + curdie = curdie->di_parent; + } + if (curdie != NULL) + curdie = curdie->di_right; + } + } /* end while (curdir != NULL) */ + + /* Write out debug_info size */ + /* Dont include length field or extension bytes */ + du = die_off - BEGIN_LEN_SIZE; + WRITE_UNALIGNED(dbg, (void *) (start_info_sec + extension_size), + (const void *) &du, sizeof(du), uwordb_size); + + + data = 0; /* Emphasise not usable now */ + + /* Write out debug_abbrev section */ + abbrevsectno = dbg->de_elf_sects[DEBUG_ABBREV]; + + curabbrev = abbrev_head; + while (curabbrev) { + char *val; + int nbytes; + int idx; + int res; + char buff1[ENCODE_SPACE_NEEDED]; + + res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx, &nbytes, + buff1, sizeof(buff1)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); + } + + GET_CHUNK(dbg, abbrevsectno, data, nbytes, error); + val = buff1; + memcpy((void *) data, (const void *) val, nbytes); + res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_tag, &nbytes, + buff1, sizeof(buff1)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); + } + val = buff1; + GET_CHUNK(dbg, abbrevsectno, data, nbytes, error); + memcpy((void *) data, (const void *) val, nbytes); + db = curabbrev->abb_children; + GET_CHUNK(dbg, abbrevsectno, data, sizeof(Dwarf_Ubyte), error); + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + + /* add attributes and forms */ + for (idx = 0; idx < curabbrev->abb_n_attr; idx++) { + res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_attrs[idx], + &nbytes, + buff1, sizeof(buff1)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); + } + val = buff1; + GET_CHUNK(dbg, abbrevsectno, data, nbytes, error); + memcpy((void *) data, (const void *) val, nbytes); + res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_forms[idx], + &nbytes, + buff1, sizeof(buff1)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); + } + val = buff1; + GET_CHUNK(dbg, abbrevsectno, data, nbytes, error); + memcpy((void *) data, (const void *) val, nbytes); + } + GET_CHUNK(dbg, abbrevsectno, data, 2, error); /* two zeros, + for last + entry, see + dwarf2 sec + 7.5.3 */ + *data = 0; + data++; + *data = 0; + + curabbrev = curabbrev->abb_next; + } + + GET_CHUNK(dbg, abbrevsectno, data, 1, error); /* one zero, + for end of + cu, see + dwarf2 sec + 7.5.3 */ + *data = 0; + + + return (int) dbg->de_n_debug_sect; +} + + +/*--------------------------------------------------------------------- + Get a buffer of section data. + section_idx is the elf-section number that this data applies to. + length shows length of returned data +----------------------------------------------------------------------*/ + /*ARGSUSED*/ /* pretend all args used */ + Dwarf_Ptr +dwarf_get_section_bytes(Dwarf_P_Debug dbg, + Dwarf_Signed dwarf_section, + Dwarf_Signed * section_idx, + Dwarf_Unsigned * length, Dwarf_Error * error) +{ + Dwarf_Ptr buf; + + if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, NULL); + } + + if (dbg->de_debug_sects == 0) { + /* no more data !! */ + return NULL; + } + if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) { + /* no data ever entered !! */ + return NULL; + } + *section_idx = dbg->de_debug_sects->ds_elf_sect_no; + *length = dbg->de_debug_sects->ds_nbytes; + + buf = (Dwarf_Ptr *) dbg->de_debug_sects->ds_data; + + dbg->de_debug_sects = dbg->de_debug_sects->ds_next; + + /* We may want to call the section stuff more than once: see + dwarf_reset_section_bytes() do not do: dbg->de_n_debug_sect--; */ + + return buf; +} + +/* + No errors possible. +*/ +void +dwarf_reset_section_bytes(Dwarf_P_Debug dbg) +{ + dbg->de_debug_sects = dbg->de_first_debug_sect; + /* No need to reset; commented out decrement. dbg->de_n_debug_sect + = ???; */ + dbg->de_reloc_next_to_return = 0; + dbg->de_sect_sa_next_to_return = 0; +} + +/* + Storage handler. Gets either a new chunk of memory, or + a pointer in existing memory, from the linked list attached + to dbg at de_debug_sects, depending on size of nbytes + + Assume dbg not null, checked in top level routine + + Returns a pointer to the allocated buffer space for the + lib to fill in, predincrements next-to-use count so the + space requested is already counted 'used' + when this returns (ie, reserved). + +*/ +Dwarf_Small * +_dwarf_pro_buffer(Dwarf_P_Debug dbg, + int elfsectno, unsigned long nbytes) +{ + Dwarf_P_Section_Data cursect; + + + cursect = dbg->de_current_active_section; + /* By using MAGIC_SECT_NO we allow the following MAGIC_SECT_NO must + not match any legit section number. test to have just two + clauses (no NULL pointer test) See dwarf_producer_init(). */ + if ((cursect->ds_elf_sect_no != elfsectno) || + ((cursect->ds_nbytes + nbytes) > cursect->ds_orig_alloc) + ) { + + /* Either the elf section has changed or there is not enough + space in the current section. + + Create a new Dwarf_P_Section_Data_s for the chunk. and have + space 'on the end' for the buffer itself so we just do one + malloc (not two). + + */ + unsigned long space = nbytes; + + if (nbytes < CHUNK_SIZE) + space = CHUNK_SIZE; + + cursect = (Dwarf_P_Section_Data) + _dwarf_p_get_alloc(dbg, + sizeof(struct Dwarf_P_Section_Data_s) + + space); + + + if (cursect == NULL) + return (NULL); + + /* _dwarf_p_get_alloc zeroes the space... */ + + cursect->ds_data = (char *) cursect + + sizeof(struct Dwarf_P_Section_Data_s); + cursect->ds_orig_alloc = space; + cursect->ds_elf_sect_no = elfsectno; + cursect->ds_nbytes = nbytes; /* reserve this number of bytes + of space for caller to fill + in */ + + /* Now link on the end of the list, and mark this one as the + current one */ + + if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) { + /* the only entry is the special one for 'no entry' so + delete that phony one while adding this initial real + one. */ + dbg->de_debug_sects = cursect; + dbg->de_current_active_section = cursect; + dbg->de_first_debug_sect = cursect; + } else { + dbg->de_current_active_section->ds_next = cursect; + dbg->de_current_active_section = cursect; + } + dbg->de_n_debug_sect++; + + return ((Dwarf_Small *) cursect->ds_data); + } + + /* There is enough space in the current buffer */ + { + Dwarf_Small *space_for_caller = (Dwarf_Small *) + (cursect->ds_data + cursect->ds_nbytes); + + cursect->ds_nbytes += nbytes; + return space_for_caller; + } +} + + +/*------------------------------------------------------------ + Given address advance and line advance, it gives + either special opcode, or a number < 0 +------------------------------------------------------------*/ +static int +_dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv) +{ + int opc; + + addr_adv = addr_adv / MIN_INST_LENGTH; + if (line_adv == 0 && addr_adv == 0) + return OPC_INCS_ZERO; + if (line_adv >= LINE_BASE && line_adv < LINE_BASE + LINE_RANGE) { + opc = + (line_adv - LINE_BASE) + (addr_adv * LINE_RANGE) + + OPCODE_BASE; + if (opc > 255) + return OPC_OUT_OF_RANGE; + return opc; + } else + return LINE_OUT_OF_RANGE; +} + +/*----------------------------------------------------------------------- + Handles abbreviations. It takes a die, searches through + current list of abbreviations for matching one. If it + finds one, it returns a pointer to it, and if it doesnt, + it returns a new one. Upto the user of this function to + link it up to the abbreviation head. If its a new one, + abb_idx has 0. +-----------------------------------------------------------------------*/ +static Dwarf_P_Abbrev +_dwarf_pro_getabbrev(Dwarf_P_Die die, Dwarf_P_Abbrev head) +{ + Dwarf_P_Abbrev curabbrev; + Dwarf_P_Attribute curattr; + int res1; + int nattrs; + int match; + Dwarf_ufixed *forms = 0; + Dwarf_ufixed *attrs = 0; + + curabbrev = head; + while (curabbrev) { + if ((die->di_tag == curabbrev->abb_tag) && + ((die->di_child != NULL && + curabbrev->abb_children == DW_CHILDREN_yes) || + (die->di_child == NULL && + curabbrev->abb_children == DW_CHILDREN_no)) && + (die->di_n_attr == curabbrev->abb_n_attr)) { + + /* There is a chance of a match. */ + curattr = die->di_attrs; + match = 1; /* Assume match found. */ + while (match && curattr) { + res1 = _dwarf_pro_match_attr(curattr, + curabbrev, + (int) curabbrev-> + abb_n_attr); + if (res1 == 0) + match = 0; + curattr = curattr->ar_next; + } + if (match == 1) + return curabbrev; + } + curabbrev = curabbrev->abb_next; + } + + /* no match, create new abbreviation */ + if (die->di_n_attr != 0) { + forms = (Dwarf_ufixed *) + _dwarf_p_get_alloc(die->di_dbg, + sizeof(Dwarf_ufixed) * die->di_n_attr); + if (forms == NULL) + return NULL; + attrs = (Dwarf_ufixed *) + _dwarf_p_get_alloc(die->di_dbg, + sizeof(Dwarf_ufixed) * die->di_n_attr); + if (attrs == NULL) + return NULL; + } + nattrs = 0; + curattr = die->di_attrs; + while (curattr) { + attrs[nattrs] = curattr->ar_attribute; + forms[nattrs] = curattr->ar_attribute_form; + nattrs++; + curattr = curattr->ar_next; + } + + curabbrev = (Dwarf_P_Abbrev) + _dwarf_p_get_alloc(die->di_dbg, sizeof(struct Dwarf_P_Abbrev_s)); + if (curabbrev == NULL) + return NULL; + + if (die->di_child == NULL) + curabbrev->abb_children = DW_CHILDREN_no; + else + curabbrev->abb_children = DW_CHILDREN_yes; + curabbrev->abb_tag = die->di_tag; + curabbrev->abb_attrs = attrs; + curabbrev->abb_forms = forms; + curabbrev->abb_n_attr = die->di_n_attr; + curabbrev->abb_idx = 0; + curabbrev->abb_next = NULL; + + return curabbrev; +} + +/*------------------------------------------------------------------ + Tries to see if given attribute and form combination + exists in the given abbreviation +-------------------------------------------------------------------*/ +static int +_dwarf_pro_match_attr(Dwarf_P_Attribute attr, + Dwarf_P_Abbrev abbrev, int no_attr) +{ + int i; + int found = 0; + + for (i = 0; i < no_attr; i++) { + if (attr->ar_attribute == abbrev->abb_attrs[i] && + attr->ar_attribute_form == abbrev->abb_forms[i]) { + found = 1; + break; + } + } + return found; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_section.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_section.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,112 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + + + +/* relocation section names */ +extern char *_dwarf_rel_section_names[]; + +/* section names */ +extern char *_dwarf_sectnames[]; + +/* struct to hold relocation entries. Its mantained as a linked + list of relocation structs, and will then be written at as a + whole into the relocation section. Whether its 32 bit or + 64 bit will be obtained from Dwarf_Debug pointer. +*/ + + + + + +/* + struct stores a chunk of data pertaining to a section +*/ +struct Dwarf_P_Section_Data_s { + int ds_elf_sect_no; /* elf section number */ + char *ds_data; /* data contained in section */ + unsigned long ds_nbytes; /* bytes of data used so far */ + unsigned long ds_orig_alloc; /* bytes allocated originally */ + Dwarf_P_Section_Data ds_next; /* next on the list */ +}; + +/* Used to allow a dummy initial struct (which we + drop before it gets used + This must not match any legitimate 'section' number. +*/ +#define MAGIC_SECT_NO -3 + +/* Size of chunk of data allocated in one alloc + Not clear if this is the best size. + Used to be just 4096 for user data, the section data struct + was a separate malloc. +*/ +#define CHUNK_SIZE (4096 - sizeof (struct Dwarf_P_Section_Data_s)) + +/* + chunk alloc routine - + if chunk->ds_data is nil, it will alloc CHUNK_SIZE bytes, + and return pointer to the beginning. If chunk is not nil, + it will see if there's enoungh space for nbytes in current + chunk, if not, add new chunk to linked list, and return + a char * pointer to it. Return null if unsuccessful. +*/ +Dwarf_Small *_dwarf_pro_buffer(Dwarf_P_Debug dbg, int sectno, + unsigned long nbytes); + +#define GET_CHUNK(dbg,sectno,ptr,nbytes,error) \ + { \ + (ptr) = _dwarf_pro_buffer((dbg),(sectno),(nbytes)); \ + if ((ptr) == NULL) { \ + DWARF_P_DBG_ERROR(dbg,DW_DLE_CHUNK_ALLOC,-1); \ + } \ + } + + + +int + _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, + Dwarf_Error * error); + +/* These are for creating ELF section type codes. +*/ +#if defined(linux) || defined(__BEOS__) || !defined(SHT_MIPS_DWARF) +/* Intel's SoftSdv accepts only this */ +#define SECTION_TYPE SHT_PROGBITS +#else +#define SECTION_TYPE SHT_MIPS_DWARF +#endif diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_types.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_types.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,296 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#endif +#include "pro_incl.h" +#include "pro_section.h" + + +/* + This function adds another type name to the + list of type names for the given Dwarf_P_Debug. + It returns 0 on error, and 1 otherwise. +*/ +Dwarf_Unsigned +dwarf_add_typename(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *type_name, Dwarf_Error * error) +{ + return + _dwarf_add_simple_name_entry(dbg, die, type_name, + dwarf_snk_typename, error); +} + +/* + The following is the generic 'add a simple name entry' + for any of the simple name sections. + + See enum dwarf_sn_kind in pro_opaque.h + +*/ +Dwarf_Unsigned +_dwarf_add_simple_name_entry(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *entry_name, + enum dwarf_sn_kind entrykind, + Dwarf_Error * error) +{ + Dwarf_P_Simple_nameentry nameentry; + Dwarf_P_Simple_name_header hdr; + char *name; + int uword_size; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return (0); + } + + if (die == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); + return (0); + } + + + nameentry = (Dwarf_P_Simple_nameentry) + _dwarf_p_get_alloc(dbg, + sizeof(struct Dwarf_P_Simple_nameentry_s)); + if (nameentry == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (0); + } + + name = _dwarf_p_get_alloc(dbg, strlen(entry_name) + 1); + if (name == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (0); + } + strcpy(name, entry_name); + + nameentry->sne_die = die; + nameentry->sne_name = name; + nameentry->sne_name_len = strlen(name); + uword_size = dbg->de_offset_size; + + hdr = &dbg->de_simple_name_headers[entrykind]; + if (hdr->sn_head == NULL) + hdr->sn_head = hdr->sn_tail = nameentry; + else { + hdr->sn_tail->sne_next = nameentry; + hdr->sn_tail = nameentry; + } + hdr->sn_count++; + hdr->sn_net_len += uword_size + nameentry->sne_name_len + 1; + + return (1); +} + + + +/* + _dwarf_transform_simplename_to_disk writes + ".rel.debug_pubnames", + ".rel.debug_funcnames", sgi extension + ".rel.debug_typenames", sgi extension + ".rel.debug_varnames", sgi extension + ".rel.debug_weaknames", sgi extension + to disk. + section_index indexes one of those sections. + entrykind is one of those 'kind's. + +*/ +int +_dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, enum dwarf_sn_kind entrykind, int section_index, /* in + de_elf_sects + etc + */ + Dwarf_Error * error) +{ + + + /* Used to fill in 0. */ + const Dwarf_Signed big_zero = 0; + + /* Used to scan the section data buffers. */ + Dwarf_P_Section_Data debug_sect; + + Dwarf_Signed debug_info_size; + + Dwarf_P_Simple_nameentry nameentry_original; + Dwarf_P_Simple_nameentry nameentry; + Dwarf_Small *stream_bytes; + Dwarf_Small *cur_stream_bytes_ptr; + Dwarf_Unsigned stream_bytes_count; + Dwarf_Unsigned adjusted_length; /* count excluding length field + */ + + + int uword_size = dbg->de_offset_size; + int extension_size = dbg->de_64bit_extension ? 4 : 0; + + Dwarf_P_Simple_name_header hdr; + + + /* ***** BEGIN CODE ***** */ + + debug_info_size = 0; + for (debug_sect = dbg->de_debug_sects; debug_sect != NULL; + debug_sect = debug_sect->ds_next) { + /* We want the size of the .debug_info section for this CU + because the dwarf spec requires us to output it below so we + look for it specifically. */ + if (debug_sect->ds_elf_sect_no == dbg->de_elf_sects[DEBUG_INFO]) { + debug_info_size += debug_sect->ds_nbytes; + } + } + + hdr = &dbg->de_simple_name_headers[entrykind]; + /* Size of the .debug_typenames (or similar) section header. */ + stream_bytes_count = extension_size + uword_size + /* Size of + length + field. */ + sizeof(Dwarf_Half) + /* Size of version field. */ + uword_size + /* Size of .debug_info offset. */ + uword_size; /* Size of .debug_names. */ + + + + nameentry_original = hdr->sn_head; + nameentry = nameentry_original; + /* add in the content size */ + stream_bytes_count += hdr->sn_net_len; + + /* Size of the last 0 offset. */ + stream_bytes_count += uword_size; + + /* Now we know how long the entire section is */ + GET_CHUNK(dbg, dbg->de_elf_sects[section_index], + stream_bytes, (unsigned long) stream_bytes_count, error); + if (stream_bytes == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (0); + } + cur_stream_bytes_ptr = stream_bytes; + + if (extension_size) { + Dwarf_Unsigned x = DISTINGUISHED_VALUE; + + WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, + (const void *) &x, sizeof(x), extension_size); + cur_stream_bytes_ptr += extension_size; + + } + /* Write the adjusted length of .debug_*names section. */ + adjusted_length = stream_bytes_count - uword_size - extension_size; + WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, + (const void *) &adjusted_length, + sizeof(adjusted_length), uword_size); + cur_stream_bytes_ptr += uword_size; + + /* Write the version as 2 bytes. */ + { + Dwarf_Half verstamp = CURRENT_VERSION_STAMP; + + WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, + (const void *) &verstamp, + sizeof(verstamp), sizeof(Dwarf_Half)); + cur_stream_bytes_ptr += sizeof(Dwarf_Half); + } + + /* Write the offset of the compile-unit. */ + WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, + (const void *) &big_zero, + sizeof(big_zero), uword_size); + cur_stream_bytes_ptr += uword_size; + + /* now create the relocation for the compile_unit offset */ + { + int res = dbg->de_reloc_name(dbg, + section_index, + extension_size + uword_size + + sizeof(Dwarf_Half) + /* r_offset */ + , + /* debug_info section name symbol */ + dbg->de_sect_name_idx[DEBUG_INFO], + dwarf_drt_data_reloc, + uword_size); + + if (res != DW_DLV_OK) { + { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (0); + } + } + } + + /* Write the size of .debug_info section. */ + WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, + (const void *) &debug_info_size, + sizeof(debug_info_size), uword_size); + cur_stream_bytes_ptr += uword_size; + + + for (nameentry = nameentry_original; + nameentry != NULL; nameentry = nameentry->sne_next) { + + /* Copy offset of die from start of compile-unit. */ + WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, + (const void *) &nameentry->sne_die->di_offset, + sizeof(nameentry->sne_die->di_offset), + uword_size); + cur_stream_bytes_ptr += uword_size; + + /* Copy the type name. */ + strcpy((char *) cur_stream_bytes_ptr, nameentry->sne_name); + cur_stream_bytes_ptr += nameentry->sne_name_len + 1; + } + + WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, + (const void *) &big_zero, + sizeof(big_zero), uword_size); + + + + + return (int) dbg->de_n_debug_sect; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_types.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,44 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + +/* pro_types.h */ + + +int _dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, enum dwarf_sn_kind entrykind, int section_index, /* in + de_elf_sects + etc + */ + Dwarf_Error * error); diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_util.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_util.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,148 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + + +#define IS_64BIT(dbg) ((dbg)->de_flags & DW_DLC_SIZE_64 ? 1 : 0) +#define ISA_IA64(dbg) ((dbg)->de_flags & DW_DLC_ISA_IA64 ? 1 : 0) + +/* definition of sizes of types, given target machine */ +#define sizeof_sbyte(dbg) sizeof(Dwarf_Sbyte) +#define sizeof_ubyte(dbg) sizeof(Dwarf_Ubyte) +#define sizeof_uhalf(dbg) sizeof(Dwarf_Half) +/* certain sizes not defined here, but set in dbg record. + See pro_init.c +*/ + +/* Computes amount of padding necessary to align n to a k-boundary. */ +/* Important: Assumes n, k both GREATER than zero. */ +#define PADDING(n, k) ( (k)-1 - ((n)-1)%(k) ) + +/* The following defines are only important for users of the +** producer part of libdwarf, and such should have these +** defined correctly (as necessary) +** by the #include done in pro_incl.h +** before the #include "pro_util.h". +** For others producer macros do not matter so 0 is a usable value, and +** zero values let compilation succeed on more non-MIPS architectures. +** A better approach would be welcome. +*/ +/* R_MIPS* are #define so #ifndef works */ +/* R_IA_64* are not necessarily #define (might be enum) so #ifndef + is useless, we use the configure script generating + HAVE_R_IA_64_DIR32LSB and HAVE_R_IA64_DIR32LSB. +*/ +#ifndef R_MIPS_64 +#define R_MIPS_64 0 +#endif +#ifndef R_MIPS_32 +#define R_MIPS_32 0 +#endif +#ifndef R_MIPS_SCN_DISP +#define R_MIPS_SCN_DISP 0 +#endif + +/* R_IA_64_DIR32LSB came before the now-standard R_IA64_DIR32LSB + (etc) was defined. This now deals with either form, + preferring the new form if available. */ +#ifdef HAVE_R_IA64_DIR32LSB +#define DWARF_PRO_R_IA64_DIR32LSB R_IA64_DIR32LSB +#define DWARF_PRO_R_IA64_DIR64LSB R_IA64_DIR64LSB +#define DWARF_PRO_R_IA64_SEGREL64LSB R_IA64_SEGREL64LSB +#define DWARF_PRO_R_IA64_SEGREL32LSB R_IA64_SEGREL32LSB +#endif +#if defined(HAVE_R_IA_64_DIR32LSB) && !defined(HAVE_R_IA64_DIR32LSB) +#define DWARF_PRO_R_IA64_DIR32LSB R_IA_64_DIR32LSB +#define DWARF_PRO_R_IA64_DIR64LSB R_IA_64_DIR64LSB +#define DWARF_PRO_R_IA64_SEGREL64LSB R_IA_64_SEGREL64LSB +#define DWARF_PRO_R_IA64_SEGREL32LSB R_IA_64_SEGREL32LSB +#endif +#if !defined(HAVE_R_IA_64_DIR32LSB) && !defined(HAVE_R_IA64_DIR32LSB) +#define DWARF_PRO_R_IA64_DIR32LSB 0 +#define DWARF_PRO_R_IA64_DIR64LSB 0 +#define DWARF_PRO_R_IA64_SEGREL64LSB 0 +#define DWARF_PRO_R_IA64_SEGREL32LSB 0 +#endif + +/* + * The default "I don't know" value can't be zero. + * Because that's the sentinel value that means "no relocation". + * In order to use this library in 'symbolic relocation mode we + * don't care if this value is the right relocation value, + * only that it's non-NULL. So at the end, we define it + * to something sensible. + */ + + + +#if defined(sun) +#if defined(sparc) +#define Get_REL64_isa(dbg) (R_SPARC_UA64) +#define Get_REL32_isa(dbg) (R_SPARC_UA32) +#define Get_REL_SEGREL_isa(dbg) (R_SPARC_NONE) /* I don't know! */ +#else /* i386 */ +#define Get_REL64_isa(dbg) (R_386_32) /* Any non-zero value is ok */ +#define Get_REL32_isa(dbg) (R_386_32) +#define Get_REL_SEGREL_isa(dbg) (R_386_NONE) /* I don't know! */ +#endif /* sparc || i386 */ +#else /* !sun */ +#ifdef HAVE_SYS_IA64_ELF_H +#define Get_REL64_isa(dbg) (ISA_IA64(dbg) ? \ + DWARF_PRO_R_IA64_DIR64LSB : R_MIPS_64) +#define Get_REL32_isa(dbg) (ISA_IA64(dbg) ? \ + DWARF_PRO_R_IA64_DIR32LSB : R_MIPS_32) + + +/* ia64 uses 32bit dwarf offsets for sections */ +#define Get_REL_SEGREL_isa(dbg) (ISA_IA64(dbg) ? \ + DWARF_PRO_R_IA64_SEGREL32LSB : R_MIPS_SCN_DISP) +#else /* HAVE_SYS_IA64_ELF_H */ + +#if !defined(linux) && !defined(__BEOS__) +#define Get_REL64_isa(dbg) (R_MIPS_64) +#define Get_REL32_isa(dbg) (R_MIPS_32) +#define Get_REL_SEGREL_isa(dbg) (R_MIPS_SCN_DISP) +#else +#define Get_REL64_isa(dbg) (1) +#define Get_REL32_isa(dbg) (1) /* these are used on linux */ +#define Get_REL_SEGREL_isa(dbg) (1) /* non zero values, see comments above */ +#endif + +#endif /* HAVE_SYS_IA64_ELF_H */ +#endif /* !sun */ + + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_vars.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_vars.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,62 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#endif +#include "pro_incl.h" +#include "pro_section.h" + +/* + This function adds another variable name to the + list of variable names for the given Dwarf_P_Debug. + It returns 0 on error, and 1 otherwise. +*/ +Dwarf_Unsigned +dwarf_add_varname(Dwarf_P_Debug dbg, + Dwarf_P_Die die, char *var_name, Dwarf_Error * error) +{ + return + _dwarf_add_simple_name_entry(dbg, die, var_name, + dwarf_snk_varname, error); + + +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_weaks.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_weaks.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,61 @@ +/* + + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#endif +#include "pro_incl.h" +#include "pro_section.h" + +/* + This function adds another weak name to the + list of weak names for the given Dwarf_P_Debug. + It returns 0 on error, and 1 otherwise. +*/ +Dwarf_Unsigned +dwarf_add_weakname(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *weak_name, Dwarf_Error * error) +{ + return + _dwarf_add_simple_name_entry(dbg, die, weak_name, + dwarf_snk_weakname, error); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/COPYING.LIB --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/COPYING.LIB Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public 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. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library 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 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/ChangeLog --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/ChangeLog Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1392 @@ +Fri Sep 7 14:04:20 CEST 2007, Michael Riepe + + * acconfig.h: + add ENABLE_SANITY_CHECKS. + + * aclocal.m4: + fix --enable-gnu-names. + + * configure.in: + add --enable-sanity-checks. + fix --enable-extended-format. + + * lib/data.c: + add _elf_sanity_checks variable. + + * lib/private.h: + declare _elf_sanity_checks and constants. + + * lib/strptr.c: + enable/disable sanity check. + + * lib/version.c: + set _elf_sanity_checks from $LIBELF_SANITY_CHECKS. + +Fri Jun 29 23:27:15 CEST 2007, Michael Riepe + + * lib/Makefile.in: + improved make -jX patch. + +Wed Jun 20 08:04:30 CEST 2007, Michael Riepe + + * lib/Makefile.in: + add "make -jX install" patch by Joel Martin. + +Tue Nov 21 21:21:12 CET 2006, Michael Riepe + + * lib/Makefile.w32: + fix Windows compilation bug. + +Thu Sep 7 17:55:42 CEST 2006, Michael Riepe + + * acconfig.h: + * aclocal.m4: + * configure.in: + * lib/config.h.w32: + * lib/gelf.h: + * lib/private.h: + * lib/sys_elf.h.in: + * lib/sys_elf.h.w32: + port to QNX Neutrino, thanks to darkelf. + +Fri Aug 25 14:46:34 CEST 2006, Michael Riepe + + * Makefile.in: + add trackinstall target. + +Mon Aug 21 20:26:47 CEST 2006, Michael Riepe + + * Makefile.in: + drop w32 from DISTSUBDIRS. + * lib/Makefile.in: + add new files to DISTFILES. + * lib/Makefile.w32: + * lib/build.bat: + * lib/config.h.w32: + * lib/libelf.def: + * lib/sys_elf.h.w32: + adopted from w32 subdirectory. + +Fri Aug 18 02:04:58 CEST 2006, Michael Riepe + + * lib/begin.c: + let getnum return a size_t. + * lib/libelf.h: + replace __value because it's a reserved word in VC++ 2005. + * lib/nlist.c: + don't declare open() on W32. + * lib/private.h: + use on W32. + * w32/Makefile.w32: + fix W32 DLL build. + * w32/build.bat: + add more examples for vcvars32.bat location. + +Fri Jul 28 00:56:00 CEST 2006, Michael Riepe + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + check for dsize == -1. + * lib/verdef.h: + * lib/verneed.h: + improve section translators. + +Tue Jul 11 18:53:00 CEST 2006, Michael Riepe + + * w32/libelf.def: + add missing functions. + +Sat Jul 8 00:50:00 CEST 2006, Michael Riepe + + * VERSION: + bump up to 0.8.9. + +Sat Jul 8 00:17:00 CEST 2006, Michael Riepe + + * lib/32.newehdr.c: + make return value compatible with Solaris. + * lib/32.newphdr.c: + handle 65535+ segments. + make return value compatible with Solaris. + * lib/cook.c: + handle 65535+ segments. + * lib/elf_repl.h: + add new definitions. + * lib/libelf.h: + add/rename functions. + * lib/newscn.c: + fix section creation (was broken in 0.8.7). + * lib/private.h: + add SHN_XINDEX and PN_XNUM in case they're missing. + centrally define LIBELF_SUCCESS and LIBELF_FAILURE. + * lib/update.c: + handle 65535+ segments. + use elf->e_phnum internally. + * lib/x.elfext.c: + add elf_getphnum(). + rename elfx_get_shnum() and elfx_get_shstrndx(). + make return values compatible with Solaris. + +Fri Jul 7 19:01:04 CEST 2006, Michael Riepe + + * VERSION: + bump up to 0.8.8. + +Fri Jul 7 18:27:25 CEST 2006, Michael Riepe + + * lib/Makefile.in: + add lib/x.elfext.c. + * lib/libelf.h: + add functions from lib/x.elfext.c. + * lib/newscn.c: + simplify _elf_update_shnum(). + +Tue Apr 25 16:26:39 CEST 2006, Michael Riepe + + * lib/gelf.h: + * lib/libelf.h: + * lib/nlist.h: + * lib/private.h: + add workaround for broken compilers. + +Mon Apr 24 16:24:32 CEST 2006, Michael Riepe + + * po/de.po: + update. + +Fri Apr 21 19:17:46 CEST 2006, Michael Riepe + + * acconfig.h: + * configure.in: + add --enable-extended-format. + * aclocal.m4: + search for msgmerge. + * lib/cook.c: + change _elf_item buffering. + handle extended format (with unusual entsize). + * lib/errors.h: + add ERROR_EHDR_SHENTSIZE and ERROR_EHDR_PHENTSIZE. + * po/Makefile.in: + use msgmerge instead of tupdate. + +Thu Oct 20 21:08:02 CEST 2005, Michael Riepe + + * lib/input.c: + * lib/update.c: + handle partial reads and writes. + +Tue Aug 16 01:48:17 CEST 2005, Michael Riepe + + * lib/begin.c: + add workaround for archive member misalignment. + * VERSION: + bump up to 0.8.7 + +Tue Jul 19 11:56:26 CEST 2005, Michael Riepe + + * README: + * w32/build.bat: + update. + * w32/libelf.def: + fix syntax. + +Tue Jun 28 00:31:24 CEST 2005, Michael Riepe + + * Makefile.in: + remove superfluous slash. + +Tue Jun 21 03:58:47 CEST 2005, Michael Riepe + + * lib/Makefile.in: + get rid of lib/pic subdir. + +Sat May 21 17:39:28 CEST 2005, Michael Riepe + + * (global): + remove my e-mail address from all copyright clauses. + +Sun May 15 23:08:30 CEST 2005, Michael Riepe + + * configure.in: + check if $CC can copile . + * lib/private.h: + #include before (fixes glibc bug). + +Sun May 8 23:40:35 CEST 2005, Michael Riepe + + * Makefile.in: + add instroot variable. + install libelf.pc. + * configure.in: + create libelf.pc. + +Sun Mar 20 15:41:22 CET 2005, Michael Riepe + + * (global): + change my e-mail address. + +Fri Jan 28 23:09:57 CET 2005, Michael Riepe + + * po/Makefile.in: + use modified gmo2msg. + * po/gmo2msg.c: + make gmo2msg output more portable. + +Thu Oct 7 11:37:09 CEST 2004, Michael Riepe + + * lib/cook.c: + only use Elf64_Shdr if __LIBELF64 is true. + +Fri Sep 17 02:55:47 CEST 2004, Michael Riepe + + * lib/elf_repl.h: + add some ABI and architecture definitions. + * w32/config.h: + manual update. + +Sat Jul 10 17:33:15 CEST 2004, Michael Riepe + + * acconfig.h: + * aclocal.m4: + * lib/errmsg.c: + check for dgettext, not for gettext. + * configure.in: + check for -lintl. + * po/Makefile.in: + use -lintl when building gmo2msg. + +Sun Jul 4 23:57:21 CEST 2004, Michael Riepe + + * Makefile.in: + add w32 subdir. + * README: + update for 0.8.6. + * configure.in: + create w32/Makefile. + +Sat Jul 3 20:42:00 CEST 2004, Michael Riepe + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + * lib/Makefile.in: + give up on . + * lib/getarsym.c: + +Wed Jun 23 01:07:46 CEST 2004, Michael Riepe + + * config.guess: + * config.sub: + update from FSF. + +Tue May 4 22:02:01 CEST 2004, Michael Riepe + + * config.guess: + * config.sub: + update from FSF. + +Tue Mar 30 15:09:00 CEST 2004, Michael Riepe + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + * lib/Makefile.in: + use to work around W32 compiler problems. + +Mon Feb 16 06:19:11 CET 2004, Michael Riepe + + * Makefile.in: + generate old-format tar file. + +Sat Jan 24 03:42:39 CET 2004, Michael Riepe + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + replace NULL with 0 -- some compilers don't like (void*). + * lib/getarsym.c: + * lib/nlist.c: + add cast to suppress compiler warning. + +Fri Jan 23 05:11:46 CET 2004, Michael Riepe + + * lib/update.c: + #undef max before #define. + +Wed Jan 21 18:15:50 CET 2004, Michael Riepe + + * lib/begin.c: + better support for Cygwin .lib archive files. + +Mon Jan 19 15:36:21 CET 2004, Michael Riepe + + * lib/libelf.h: + * lib/memset.c: + include unconditionally. + +Fri Jan 16 23:13:25 CET 2004, Michael Riepe + + * aclocal.m4: + support Intel C Compiler. + * lib/32.newehdr.c: + * lib/32.newphdr.c: + remove elf->e_free_ehdr and elf->e_free_phdr. + * lib/cook.c: + always allocate ehdr and phdr. + * lib/end.c: + always deallocate ehdr and phdr. + * lib/private.h: + remove elf->e_free_ehdr and elf->e_free_phdr. + change valid_type to suppress compiler warning. + * lib/update.c: + not necessary to update elf->e_ehdr and elf->e_phdr. + +Thu Jan 15 22:43:00 CET 2004, Michael Riepe + + * VERSION: + bump up to 0.8.6. + * configure.in: + check for __int64. + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + * lib/gelf.h: + * lib/nlist.h: + test _WIN32 macro. + * lib/begin.c: + add (off_t) cast to suppress compiler warning. + * lib/libelf.h: + * lib/memset.c: + conditionally include for size_t. + * lib/nlist.c: + declare open() on W32 systems. + +Tue Dec 16 20:02:30 CET 2003, Michael Riepe + + * Makefile.in: + let disttest target make dist again. + +Sat Dec 13 16:14:31 CET 2003, Michael Riepe + + * lib/update.c: + call lseek before ftruncate. + +Fri Dec 5 16:25:16 CET 2003, Michael Riepe + + * aclocal.m4: + add explanation for --enable-maintainer-mode + * lib/Makefile.in: + * po/Makefile.in: + add instroot make variable + * README: + add hint how to use it + +Thu Nov 6 17:35:00 CET 2003, Michael Riepe + + * Makefile.in: + * lib/Makefile.in: + * po/Makefile.in: + add check targets + add MANIFEST to distribution + * aclocal.m4: + add mr_PACKAGE macro + * configure.in: + use mr_PACKAGE macro + +Sat Oct 25 15:22:59 CEST 2003, Michael Riepe + + * lib/elf_repl.h: + add EM_SPARC64 + +Thu Oct 9 23:08:56 CEST 2003, Michael Riepe + + * lib/x.movscn.c: + * lib/x.remscn.c: + verify that file is really an ELF file + +Wed Oct 8 17:10:09 CEST 2003, Michael Riepe + + * config.guess: + * config.sub: + latest versions from FSF + +Sat May 24 18:55:14 CEST 2003, Michael Riepe + + * config.guess: + latest version from FSF + * lib/Makefile.in: + * lib/libelf.h: + * lib/x.movscn.c: + * lib/x.remscn.c: + add elfx_movscn() and elfx_remscn() + * lib/newscn.c: + update e_shnum properly + * lib/private.h: + declare _elf_update_shnum() + +Fri May 23 18:25:48 CEST 2003, Michael Riepe + + * aclocal.m4: + provide name suffixes only + * lib/Makefile.in: + use name suffixes + +Fri May 23 01:24:26 CEST 2003, Michael Riepe + + * README: + update for 0.8.5 + add section about LFS + * config.guess: + latest version from FSF + * configure.in: + * lib/Makefile.in: + use local pic object directory + * lib/checksum.c: + detect d_buf == NULL + +Sun May 18 16:49:10 CEST 2003, Michael Riepe + + * VERSION: + bump up to 0.8.5 + * lib/strptr.c: + make elf_strptr() work safely with fragmented string tables + * lib/errors.h: + new error code and message for elf_strptr() + * po/de.po: + * po/libelf.po: + regenerated + +Mon May 12 15:29:12 CEST 2003, Michael Riepe + + * lib/update.c: + improved fix for elf_update `null buffer' bug + +Mon May 12 00:34:44 CEST 2003, Michael Riepe + + * config.guess: + * config.sub: + latest versions from FSF + +Sun May 11 01:44:06 CEST 2003, Michael Riepe + + * lib/verdef.h: + * lib/verneed.h: + fix elf_update `null buffer' error. + Thanks to Bart Trojanowski who reported the bug. + +Wed May 7 20:26:17 CEST 2003, Michael Riepe + + * configure.in: + fix maintainer mode default + * lib/verdef.h: + * lib/verneed.h: + only check d_buf if there is at least one element + +Mon Mar 31 17:08:04 CEST 2003, Michael Riepe + + * VERSION: + bump up to 0.8.4 + +Sun Mar 23 16:06:43 CET 2003, Michael Riepe + + * configure.in: + fix --enable-compat + +Thu Feb 27 14:35:12 CET 2003, Michael Riepe + + * Makefile.in: + add `test-dist' target + * lib/errors.h: + new error code + * po/de.po: + * po/libelf.pot: + regenerated + +Wed Feb 26 17:48:58 CET 2003, Michael Riepe + + * config.guess: + * config.sub: + latest versions from FSF + +Wed Jan 15 22:50:53 CET 2003, Michael Riepe + + * lib/begin.c: + fix overflow check + +Sun Jan 12 04:27:31 CET 2003, Michael Riepe + + * configure.in: + prefer int for __libelf_i32_t (if int has 32 bits) + +Thu Jan 2 17:40:22 CET 2003, Michael Riepe + + * README: + update for 0.8.3 + * config.guess: + * config.sub: + update from ftp.gnu.org + * lib/cook.c: + require space for one SHDR only + * lib/elf_repl.h: + fix DT_ENCODING value + +Tue Dec 31 16:27:19 CET 2002, Michael Riepe + + * lib/cook.c: + honor ELF extensions for >= 0xff00 sections + * lib/elf_repl.h: + add definitions from lates ELF spec + * lib/errors.h: + * po/libelf.pot: + * po/de.po: + new error message + * lib/private.h: + define missing pieces + * lib/update.c: + handle >= 0xff00 sections + +Mon Dec 23 00:23:20 CET 2002, Michael Riepe + + * lib/Makefile.in: + fix dependencies. + * lib/cook.c: + add quirks mode for broken 64-bit architectures. + * lib/update.c: + do not override sh_entsize unless it's set to 0. + * lib/verdef.h: + * lib/verneed.h: + work around possible SEGV in translation routines. + +Sat Dec 14 23:33:10 CET 2002, Michael Riepe + + * ChangeLog: + add missing entries for 0.8.2 release. + * VERSION: + bump up to 0.8.3. + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + * lib/verdef.h: + * lib/verneed.h: + fix ISO C violations (required for MacOS X). + * po/gmo2msg.c: + create SUSv3 compliant .msg files. + +Thu Jun 11 19:00:19 CEST 2002, Michael Riepe + + * README: + update for 0.8.2. + * VERSION: + bump up to 0.8.2. + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + fix typos in for loop. + * lib/nlist.c: + add O_BINARY to file mode + (defaults to 0 on systems that lack it). + +Tue Dec 25 14:42:51 CET 2001, Michael Riepe + + * VERSION: + set version to 0.8.0. + * README: + update version. + +Tue Oct 30 17:05:03 CET 2001, Michael Riepe + + * Makefile.in: + use uid/gid=0 when creating the distribution tar file. + +Mon Oct 15 23:47:10 CEST 2001, Michael Riepe + + * configure.in: + check for and . + create ./pic when configuring. + * lib/Makefile.in: + move .o to ../pic/$@, not ../pic. + * lib/begin.c: + define struct ar_hdr and friends if is missing. + use lseek(..., SEEK_END). + * lib/input.c: + use lseek(..., SEEK_SET). + * lib/nlist.c: + include conditionally. + define O_RDONLY if it is missing. + * lib/private.h: + define SEEK_{SET,CUR,END} if they're missing. + * lib/update.c: + explicitly pass file descriptor to _elf_output(). + use lseek(..., SEEK_SET). + +Tue Oct 9 22:46:01 CEST 2001, Michael Riepe + + * aclocal.m4: + remove superfluous case. + +Mon Oct 8 17:56:04 CEST 2001, Michael Riepe + + * lib/opt.delscn.c: + handle versioning sections properly. + +Mon Oct 8 17:02:43 CEST 2001, Michael Riepe + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + override encoding when calculating the destination buffer + size for translation to a file. + +Sun Oct 7 21:31:01 CEST 2001, Michael Riepe + + * configure.in: + drop OBJS64; always compile 64-bit sources. + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + add translators for versioning structures. + * lib/Makefile.in: + drop OBJS64; add versioning support files. + * lib/errors.h: + add error codes for versioning support. + * lib/gelfehdr.c: + * lib/gelfphdr.c: + * lib/gelfshdr.c: + * lib/gelftrans.c: + * lib/swap64.c: + guard code with `#if __LIBELF64'. + * lib/private.h: + add translator declarations. + * po/de.po: + * po/libelf.pot: + add error messages for versioning support. + +Sun Oct 7 16:54:15 CEST 2001, Michael Riepe + + * acconfig.h: + * configure.in: + improve auto-configuration. + * lib/Makefile.in: + * po/Makefile.in + let users override distdir. + * lib/cook.c: + improved bugfix based on new auto-configuration. + * lib/getdata.c: + prepare src first to prevent SEGV. + * lib/private.h: + * lib/update.c: + cosmetic changes. + +Sun Oct 7 05:50:19 CEST 2001, Michael Riepe + + * configure.in: + * lib/cook.c: + fix compilation problem on Linux (SHT_SUNW_ver* undefined). + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + make translator functions calculate the destination size. + add _elf32_xltsize and _elf64_xltsize entry points. + * lib/private.h: + declare _elf32_xltsize and _elf64_xltsize. + * lib/getdata.c: + * lib/update.c: + use _elf32_xltsize and _elf64_xltsize. + +Fri Oct 5 20:35:31 CEST 2001, Michael Riepe + + * lib/elf_repl.h: + add DT_VERSYM. + * lib/ext_types.h: + correct type names. + * lib/libelf.h: + add ELF_T_VDEF and ELF_T_VNEED. + * lib/32.fsize.c: + add table entries for versioning structures. + * lib/cook.c: + replace _elf_scn_types[] with _elf_scn_type(). + * lib/private.h: + likewise; also remove valid_scntype() macro. + * lib/update.c: + call _elf_scn_type(), but do not set sh_entsize + for ELF_T_VDEF / ELF_T_VNEED. + * acconfig.h: + * lib/sys_elf.h.in: + added __LIBELF_SYMBOL_VERSIONS. + * configure.in: + check for symbol versioning definitions. + * lib/Makefile.in: + added gelf.h dependency. + +Wed Oct 3 22:46:33 CEST 2001, Michael Riepe + + * lib/swap64.c: + new file; separate 64-bit functions. + * lib/64.xlatetof.c: + remove 64-bit conversion functions. + * lib/byteswap.h: + replace casts to long / unsigned long. + add prototypes for 64-bit conversion functions. + * configure.in: + * lib/Makefile.in: + add lib/swap64.c. + * lib/ext_types.h: + add type definitions for versioning. + * lib/elf_repl.h: + * lib/gelf.h: + cosmetic changes. + +Wed Oct 3 00:00:27 CEST 2001, Michael Riepe + + * lib/elf_repl.h: + added lots of new definitions. + * lib/gelf.h: + * lib/libelf.h: + * lib/sys_elf.h.in: + cosmetic changes. + +Fri Sep 28 22:42:36 CEST 2001, Michael Riepe + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + remove `const' when compiling with -fPIC. + +Fri Sep 28 20:14:42 CEST 2001, Michael Riepe + + * README: + add pointers to documentation. + * lib/64.xlatetof.c: + fixed conversion thinko. + (Jakub Jelinek found this - thanks!) + * lib/gelf.h: + * lib/32.fsize.c: + add gelf_msize. + * lib/libelf.h: + add comment that elf{32,64}_checksum is missing. + +Tue Sep 11 02:43:47 CEST 2001, Michael Riepe + + * README: + corrected typo. + * lib/cook.c: + * lib/private.h: + * lib/update.c: + replaces _ELFxx_ALIGN_xHDR with _fsize() call. + +Sun Sep 2 20:58:09 CEST 2001, Michael Riepe + + * Makefile.in: + * configure.in: + * lib/Makefile.in: + * po/Makefile.in: + add maintainer mode. + +Sat Sep 1 15:11:42 CEST 2001, Michael Riepe + + * lib/sys_elf.h.in: add more fixes for broken files. + +Sat Sep 1 05:01:16 CEST 2001, Michael Riepe + + * ChangeLog: major update. Yes, I'm back. + + * COPYING.LIB: updated version from FSF. + + * README: updated for 0.7.1. + +Thu Apr 20 17:09:41 CEST 2000, Michael Riepe + + * lib/gelftrans.c: + * lib/elf_repl.h: + add explicit casts to ELF64_R_SYM and ELF64_R_INFO. + +Thu Apr 13 20:15:45 CEST 2000, Michael Riepe + + * lib/update.c: better checks for overlapping sections. + + * lib/errors.h: + * po/de.po: + * po/libelf.pot: + new error message. + +Thu Apr 6 19:15:46 CEST 2000, Michael Riepe + + * lib/strptr.c: rename `sd' variable. + +Fri Mar 31 20:11:14 CEST 2000, Michael Riepe + + * Makefile.in: also pass CPPFLAGS and LDFLAGS to config.status. + +Fri Mar 31 20:02:55 CEST 2000, Michael Riepe + + * aclocal.m4: add -DPIC define when building position-independent code. + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + * lib/errmsg.c: + make array members const when PIC is undefined. + +Fri Mar 31 14:42:32 CEST 2000, Michael Riepe + + * lib/32.newehdr.c: make _elf_newehdr() function private again. + + * lib/32.newphdr.c: make _elf_newphdr() function private again. + + * lib/strptr.c: add support for 64-bit ELF format. + +Wed Mar 29 18:49:43 CEST 2000, Michael Riepe + + * lib/gelfshdr.c: remove ELF class check. + +Mon Mar 27 01:24:50 CEST 2000, Michael Riepe + + * lib/gelf.h: #include when compiling libelf. + +Sun Mar 26 15:02:54 CEST 2000, Michael Riepe + + * lib/private.h: #include header file. + + * lib/gelfehdr.c: move gelf_newehdr() function to lib/32.newehdr.c. + + * lib/gelfphdr.c: move gelf_newphdr() function to lib/32.newphdr.c. + + * lib/32.newehdr.c: add gelf_newehdr() function. + + * lib/32.newphdr.c: add gelf_newphdr() function. + + * lib/gelfshdr.c: + * lib/gelftrans.c: + remove explicit include. + +Sun Mar 26 06:22:20 CEST 2000, Michael Riepe + + * acconfig.h: + * configure.in: + * lib/private.h: + * lib/sys_elf.h.in: + rename NEED_LINK_H to __LIBELF_NEED_LINK_H. + + * lib/32.newehdr.c: make _elf_newehdr() function public. + + * lib/32.newphdr.c: make _elf_newphdr() function public. + + * lib/gelf.h: + include if needed. + choke if 64-bit is not supported. + add generic versions of ELF32_* and ELF64_* macros. + + * lib/gelftrans.c: + define ELF32_R_* and ELF64_R_* macros (missing on some systems). + +Sun Mar 26 05:27:15 CEST 2000, Michael Riepe + + * configure.in: + add check for existing header. + build new source files when 64-bit is enabled. + + * lib/Makefile.in: + add new source files. + make install-compat if --enable-compat was given. + + * po/de.po: + * po/libelf.pot: + new error messages. + +Sun Mar 26 05:00:20 CEST 2000, Michael Riepe + + * Makefile.in: + * lib/Makefile.in: + * po/Makefile.in: + remove Makefile last in `make distclean'. + + * aclocal.m4: explicitly state the default in --enable-* help texts. + + * configure.in: + set ALL_LINGUAS automatically. + add `--enable-compat' option. + + * lib/private.h: add sd_scn member to struct Scn_Data. + + * lib/cook.c: + * lib/end.c: + * lib/getdata.c: + * lib/newdata.c: + * lib/opt.delscn.c: + * lib/rawdata.c: + * lib/update.c: + handle new sd_scn member. + + * lib/gelf.h: new public header file. + + * lib/gelfehdr.c: new file, implements the gelf_getehdr(), + gelf_update_ehdr() and gelf_newehdr() functions. + + * lib/gelfphdr.c: new file, implements the gelf_getphdr(), + gelf_update_phdr() and gelf_newphdr() functions. + + * lib/gelfshdr.c: new file, implements the gelf_getshdr() + and gelf_update_shdr() functions. + + * lib/gelftrans.c: new file, implements the gelf_getsym(), + gelf_update_sym(), gelf_getdyn(), gelf_update_dyn(), + gelf_getrela(), gelf_update_rela(), gelf_getrel() and + gelf_update_rel() functions. + + * lib/begin.c: add gelf_getclass() function. + + * lib/32.fsize.c: add gelf_fsize() function. + + * lib/32.getphdr.c: make _elf_getphdr() function public. + + * lib/64.xlatetof.c: + add gelf_xlatetom() and gelf_xlatetof() functions. + remove `const' from array members. + + * lib/errors.h: add GElf error messages. + + * po/de.po: + * po/libelf.pot: + new error message. + +Thu Nov 4 21:17:34 CET 1999, Michael Riepe + + * lib/32.xlatetof.c: + * lib/errmsg.c: + * po/gmo2msg.c: + remove `const' from array members. + +Thu Nov 4 20:16:36 CET 1999, Michael Riepe + + * lib/Makefile.in: add assert.c; remove stamp-h in `make distclean'. + + * lib/assert.c: new file, implements the __elf_assert() function. + + * lib/private.h: use __elf_assert() in elf_assert() macro. + +Wed Mar 17 16:21:02 CET 1999, Michael Riepe + + * configure.in: add "de" to ALL_LINGUAS. + + * lib/elf_repl.h: lots of new #defines. + + * lib/hash.c: + * lib/libelf.h: + elf_hash() takes an `const unsigned char *'. + + * po/gmo2msg.c: copy comments from .gmo file. + +Fri Mar 5 16:28:08 CET 1999, Michael Riepe + + * VERSION: set version to 0.7.1. + + * po/de.po: new file. + +Fri Nov 27 22:24:00 MET 1998, Michael Riepe + + * lib/memset.c: rename and rewrite. + * lib/private.h: rename __memset. + +Tue Aug 25 17:17:18 MEST 1998, Michael Riepe + + * aclocal.m4: remove superfluous #include. + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: fix for picky instances of cpp(1). + +Sun Aug 23 18:26:53 MEST 1998, Michael Riepe + + * aclocal.m4: + * lib/Makefile.in: add DEPSHLIBS, set to -lc for Linux. + + * README: add DEPSHLIBS description. + +Sat Aug 22 15:50:41 MEST 1998, Michael Riepe + + * lib/begin.c: add workaround for broken ar(1) & friends. + + * lib/32.getshdr.c: fix typo. + +Thu Aug 6 18:11:52 MEST 1998, Michael Riepe + + * lib/getdata.c: fixed SEGV bug. + + * lib/cook.c: + * lib/getdata.c: + * lib/newdata.c: + * lib/rawdata.c: + * lib/private.h: removed sd_scn and (Elf_Data*) casts. + +Fri Jun 12 21:24:50 MEST 1998, Michael Riepe + + * lib/*.c: move rcsid[] after . + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: replace broken Exn() macro with Cat2(). + + * lib/64.xlatetof.c: change `char*' to `unsigned char*'. + + * lib/private.h: add `extern char *realloc();'. + + * aclocal.m4: + * configure.in: remove leading spaces in cpp directives. + +Sun Jun 7 16:02:31 MEST 1998, Michael Riepe + + * README: update for 0.7.0 release. + +Sun Jun 4 15:26:49 MEST 1998, Michael Riepe + + * acconfig.h: add __libelf64* and __libelf_*_t. + + * configure.in: clean up, add checks for 64-bit support. + + * lib/64.xlatetof.c: new file, based on lib/32.xlatetof.c. + + * lib/Makefile.in: add target for 64.xlatetof.o. + + * lib/cook.c: check for 32-bit overflow. + + * lib/elf_repl.h: + * lib/ext_types.h: add 64-bit data types. + + * lib/private.h: add 64-bit definitions. + + * lib/sys_elf.h.in: add __LIBELF64* and __libelf_*_t. + + * lib/update.c: add full 64-bit support. + +Mon Jun 1 16:29:07 MEST 1998, Michael Riepe + + * VERSION: change version to 0.7.0. + + * configure.in: + add lib/sys_elf.h to AC_CONFIG_HEADER. + new option --disable-elf64. + + * Makefile.in: add target for lib/sys_elf.h. + + * acconfig.h: add __LIBELF_HEADER_ELF_H. + + * lib/Makefile.in: add sys_elf.h(.in). + + * lib/32.fsize.c: + * lib/32.getehdr.c: + * lib/32.getphdr.c: + * lib/32.getshdr.c: + * lib/32.newehdr.c: + * lib/32.newphdr.c: + * lib/cook.c: + * lib/getdata.c: + * lib/libelf.h: + * lib/newscn.c: + * lib/nlist.c: + * lib/opt.delscn.c: + * lib/private.h: + * lib/update.c: + merged with 64bit code. + + * lib/begin.c: + * lib/input.c: + bug fixes. + +Fri Aug 1 19:33:33 MEST 1997, Michael Riepe + + * VERSION: change version to 0.6.5. + + * lib/libelf.h: add declaration for elf_memory. + + * lib/private.h: add e_memory flag. + + * lib/begin.c: add elf_memory, change archive freezing logic. + + * lib/end.c: do not free e_data if e_memory is set. + +Tue Oct 22 21:31:56 MEST 1996, Michael Riepe + + * (all files): add RCS Id, import to CVS. + + * Makefile.in: pass $(CC) to config.status. + + * README: change for upcoming 0.6.5 release. + + * aclocal.m4 (mr_ENABLE_NLS): add --enable-gnu-names option + + * configure.in: change search order for . + + * lib/begin.c (_elf_arhdr): add check for truncated archive member. + + * lib/cook.c (_elf32_cook): add checks for misaligned tables. + + * lib/errors.h: + fix wrong error message (ERROR_WRONLY). + add error messages for misaligned tables. + + * lib/private.h: add constants for table alignments. + + * po/Makefile.in: do not run mkinstalldirs directly, use $(SHELL). + + * po/libelf.pot: rebuild. + +Tue Jul 30 17:22:41 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.6.4. + + * Makefile.in: + add DISTSUBDIRS. + add po/Makefile target. + + * po/Makefile.in: + * po/gmo2msg.c: + * po/libelf.pot: + * po/stamp-po: + new files. + + * aclocal.m4 (mr_ENABLE_NLS): + add MSGFILES. + set GMOFILES, MSGFILES and POFILES even if NLS is disabled. + + * configure.in: + add ALL_LINGUAS. + + * lib/nlist.c: + call elf_errno() to clear pending error. + +Tue Jul 28 23:53:44 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.6.3. + + * configure.in: fix creation of sys_elf.h. + + * lib/Makefile.in: + move elf_repl.h to PRIVHDRS. + do not depend on HDRS and AUXHDRS. + +Sat Jul 27 18:27:09 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.6.2. + + * Makefile.in: + remove support from SUBDIRS. + remove subdirs/Makefile target. + + * acconfig.h: + add ENABLE_DEBUG. + remove HAVE_NLS. + + * aclocal.m4: + add mr_ENABLE_DEBUG. + + * configure.in: + use mr_ENABLE_DEBUG. + + * lib/Makefile.in: + add LD variable. + add elf_repl.h to DISTFILES. + + * lib/libelf.h: + add check for __LIBELF_INTERNAL__. + + * lib/private.h: + #define __LIBELF_INTERNAL__. + use ENABLE_DEBUG. + + * support/elf.h: + move to lib/elf_repl.h. + + * support/Makefile.in: + remove. + +Sat Jul 27 06:25:23 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.6.1. + + * aclocal.m4: add shared library support for sparc-sun-solaris2. + + * lib/libelf.h.in: remove. + + * lib/libelf.h: new file. + + * configure.in: + remove broken check for existing installation. + remove @install_headers@ and @elf_h@. + do not build libelf.h from libelf.h.in. + create lib/sys_elf.h. + + * lib/Makefile.in: + remove libelf.h and $(AUXHDRS) targets. + remove libelf.h.in from DISTFILES. + add libelf.h to DISTFILES. + add dummy_shlib target for broken make. + +Sat Jul 27 01:01:45 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.6.0. + + * lib: new directory. + + * config.sub: + * config.guess: + new files. + + * shared: + * shared/Makefile.in: + remove. + + * aclocal.m4: + * configure.in: + add shared library check. + + * Makefile.in: + * lib/Makefile.in: + change for new directory structure. + integrate shared library support. + + * Makefile.in: + remove libelf.lsm from DISTFILES. + + * libelf.lsm: remove. + +Thu Jul 25 19:35:05 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.5.9. + + * aclocal.m4: rewrite NLS check. + +Tue Jul 23 18:59:05 MET DST 1996, Michael Riepe + + * Makefile.in: add install-compat and uninstall-compat targets. + + * configure.in: + * aclocal.m4: + fix check for NLS support. + + * acconfig.h: add HAVE_CATGETS and HAVE_GETTEXT. + + * errmsg.c (elf_errmsg): use HAVE_GETTEXT. + +Sun Jul 21 22:52:02 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.5.8. + + * private.h: + * 32.getshdr.c: + * cook.c: + * end.c: + * newscn.c: + * opt.delscn.c: + * update.c: + change allocation of section headers. + + * errors.h: fix speeling error. + +Sat Jul 13 22:51:16 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.5.7. + + * private.h: add e_dsize member to struct Elf. + + * begin.c (elf_begin): set e_dsize. + + * update.c (_elf32_update_pointers): + never let e_data become shorter than e_dsize bytes. + use correct base pointer. + +Sat Jun 15 16:28:50 MET DST 1996, Michael Riepe + + * 32.xlatetof.c: change `char' to `unsigned char'. + +Tue May 28 19:00:30 MET DST 1996, Michael Riepe + + * Makefile.in: + HP-UX make wants non-empty target, change it. + add targets for TAGS and libelf.po. + + * errors.h: mark strings for GNU gettext. + + * mkmsgs: recognize new errors.h format. + + * errmsg.c (elf_errmsg): add gettext support. + +Mon May 27 20:30:30 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.5.6. + + * aclocal.m4: + * configure.in: use new AC_CACHE_CHECK macro. + + * Makefile.in: + * shared/Makefile.in: use @...dir@. + + * Makefile.in: pass $(SRCS) and $(OBJS) to shared/Makefile. + +Sat May 25 01:00:15 MET DST 1996, Michael Riepe + + * update.c (elf_update): assert e_data is malloc'ed. + + * begin.c (elf_begin): mmap e_data if possible. + + * end.c (elf_end): munmap e_data if necessary. + + * input.c (_elf_mmap): new function. + + * private.h: add _elf_mmap and e_unmap_data. + + * errmsg.c: make pointer array constant. + +Thu May 23 19:24:47 MET DST 1996, Michael Riepe + + * update.c (elf_update): mmap(MAP_SHARED) wants non-empty file. + +Tue May 21 15:33:07 MET DST 1996, Michael Riepe + + * begin.c (elf_begin): re-read memory image of archive members. + + * cook.c (_elf32_item): + * getdata.c (_elf32_cook_scn): always use memory image. + + * update.c (_elf_update): use mmap if possible. + + * configure.in: check for mmap. + +Mon May 20 18:15:54 MET DST 1996, Michael Riepe + + * nlist.c (_elf_nlist): fix broken st_name range check. + + * update.c (_elf32_write): check status of elf_getdata. + + * cook.c (_elf32_item): + * getdata.c (_elf32_cook_scn): + use memory image when file is not an archive member. + + * rawdata.c (elf_rawdata): copy raw image rather than referencing it. + +Wed May 15 20:04:39 MET DST 1996, Michael Riepe + + * rawdata.c (elf_rawdata): use raw image if it is present. + + * cntl.c (elf_cntl): fix archive handling, ignore ELF_C_FDREAD for non-ELF files. + +Fri May 10 17:16:44 MET DST 1996, Michael Riepe + + * begin.c (_elf_arhdr): fix handling of long archive member names. + + * configure.in: move version information to external file. + + * Makefile.in: add VERSION to DISTFILES. + + * VERSION: new file. + +Sat May 4 20:56:43 MET DST 1996, Michael Riepe + + * configure.in: change version to 0.5.5. + + * Makefile.in: add libelf.lsm and ChangeLog to DISTFILES. + + * rawdata.c: reorder cases to avoid unnecessary malloc/free. + + * all files: update copyright phrase. + + * ChangeLog: + * libelf.lsm: new files. + +Sun Oct 29 19:34:00 MET 1995, Michael Riepe + + * configure.in: change version to 0.5.3. + + * Makefile.in: + * shared/Makefile.in: add opt.delscn.c. + + * libelf.h.in: add declaration for elf_delscn. + + * opt.delscn.c: new file. + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/INSTALL --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/INSTALL Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,176 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/MANIFEST --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/MANIFEST Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,95 @@ +25275 COPYING.LIB +34569 ChangeLog +7462 INSTALL +5904 Makefile.in +12535 README +7 VERSION +2951 acconfig.h +9377 aclocal.m4 +43611 config.guess +3987 config.h.in +31160 config.sub +110753 configure +11732 configure.in +2186 install-sh +4794 lib/32.fsize.c +1552 lib/32.getehdr.c +1553 lib/32.getphdr.c +1660 lib/32.getshdr.c +2177 lib/32.newehdr.c +3051 lib/32.newphdr.c +12318 lib/32.xlatetof.c +14217 lib/64.xlatetof.c +7986 lib/Makefile.in +3999 lib/Makefile.w32 +1115 lib/assert.c +10791 lib/begin.c +1685 lib/build.bat +3562 lib/byteswap.h +3933 lib/checksum.c +1897 lib/cntl.c +4851 lib/config.h.w32 +12550 lib/cook.c +1179 lib/data.c +24540 lib/elf_repl.h +2895 lib/end.c +2133 lib/errmsg.c +1033 lib/errno.c +6218 lib/errors.h +8103 lib/ext_types.h +993 lib/fill.c +2396 lib/flag.c +5099 lib/gelf.h +4147 lib/gelfehdr.c +3961 lib/gelfphdr.c +3753 lib/gelfshdr.c +9451 lib/gelftrans.c +1171 lib/getarhdr.c +2417 lib/getarsym.c +1092 lib/getbase.c +3837 lib/getdata.c +1349 lib/getident.c +1445 lib/getscn.c +1207 lib/hash.c +2558 lib/input.c +1084 lib/kind.c +1214 lib/libelf.def +8157 lib/libelf.h +1501 lib/memset.c +1094 lib/ndxscn.c +1553 lib/newdata.c +3484 lib/newscn.c +1352 lib/next.c +1603 lib/nextscn.c +5894 lib/nlist.c +1447 lib/nlist.h +5067 lib/opt.delscn.c +12797 lib/private.h +1282 lib/rand.c +2538 lib/rawdata.c +1469 lib/rawfile.c +3389 lib/strptr.c +2281 lib/swap64.c +3808 lib/sys_elf.h.in +4066 lib/sys_elf.h.w32 +25824 lib/update.c +6880 lib/verdef.h +1582 lib/verdef_32_tof.c +1582 lib/verdef_32_tom.c +1610 lib/verdef_64_tof.c +1610 lib/verdef_64_tom.c +7131 lib/verneed.h +1431 lib/version.c +4234 lib/x.elfext.c +2717 lib/x.movscn.c +2866 lib/x.remscn.c +238 libelf.pc.in +619 mkinstalldirs +4589 po/Makefile.in +8748 po/de.gmo +52 po/de.msg +11328 po/de.po +3007 po/gmo2msg.c +6483 po/libelf.pot +10 po/stamp-po +10 stamp-h.in diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/Makefile.in Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,198 @@ +# Makefile for libelf. +# Copyright (C) 1995 - 2005 Michael Riepe +# +# This library 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 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# @(#) $Id: Makefile.in,v 1.29 2006/08/25 12:46:34 michael Exp $ + +instroot = + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@ + +pkgdir = $(libdir)/pkgconfig + +MV = mv -f +RM = rm -f +LN_S = @LN_S@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ + +# no user serviceable parts below + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ + +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +VPATH = @srcdir@ + +SUBDIRS = lib @POSUB@ +DISTSUBDIRS = lib po + +DISTFILES = \ + acconfig.h aclocal.m4 ChangeLog config.guess config.h.in \ + config.sub configure configure.in COPYING.LIB INSTALL install-sh \ + Makefile.in mkinstalldirs README stamp-h.in VERSION libelf.pc.in + +all: all-recursive all-local +check: check-recursive check-local +install: install-recursive install-local +uninstall: uninstall-recursive uninstall-local +mostlyclean: mostlyclean-recursive mostlyclean-local +clean: clean-recursive clean-local +distclean: distclean-recursive distclean-local +maintainer-clean: maintainer-clean-recursive maintainer-clean-local + +install-compat uninstall-compat: + cd lib && $(MAKE) $@ + +all-recursive check-recursive install-recursive uninstall-recursive \ +clean-recursive distclean-recursive mostlyclean-recursive \ +maintainer-clean-recursive: + @subdirs="$(SUBDIRS)"; for subdir in $$subdirs; do \ + target=`echo $@|sed 's,-recursive,,'`; \ + echo making $$target in $$subdir; \ + (cd $$subdir && $(MAKE) $$target) || exit 1; \ + done + +all-local: + +check-local: + +install-local: $(srcdir)/mkinstalldirs libelf.pc + $(SHELL) $(srcdir)/mkinstalldirs $(instroot)$(pkgdir) + $(INSTALL_DATA) libelf.pc $(instroot)$(pkgdir) + +uninstall-local: + $(RM) $(instroot)$(pkgdir)/libelf.pc + +mostlyclean-local: + $(RM) *~ core errlist + +clean-local: mostlyclean-local + +distclean-local: clean-local + $(RM) config.cache config.h config.log config.status stamp-h + $(RM) Makefile + $(RM) libelf.pc + +maintainer-clean-local: distclean-local + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + $(RM) config.h.in configure stamp-dist + $(RM) -r $(distdir) + +# maintainer only + +MAINT = @MAINT@ + +distdir = $(PACKAGE)-$(VERSION) +DISTPERMS = --owner=root --group=root --numeric-owner +$(MAINT)dist: ./stamp-dist +$(MAINT)./stamp-dist: $(DISTFILES) + $(RM) -r $(distdir) + mkdir $(distdir) + files="$(DISTFILES)"; for file in $$files; do \ + ln $(srcdir)/$$file $(distdir) || \ + cp -p $(srcdir)/$$file $(distdir) || exit 1; \ + done + subdirs="$(DISTSUBDIRS)"; for subdir in $$subdirs; do \ + (cd $$subdir && $(MAKE) dist) || exit 1; \ + done + cd $(distdir) && \ + find . -type f ! -name MANIFEST -exec wc -c {} \; | \ + sed 's, \./, ,' | sort -k2 >MANIFEST + -$(RM) $(distdir).tar.gz.bak $(PACKAGE).tar.gz + -$(MV) $(distdir).tar.gz $(distdir).tar.gz.bak + tar cvohfz $(distdir).tar.gz $(DISTPERMS) $(distdir) + $(LN_S) $(distdir).tar.gz $(PACKAGE).tar.gz + $(RM) stamp-dist && echo timestamp > stamp-dist + +$(MAINT)check-dist: + $(RM) -r disttest + mkdir disttest + @echo 'unset CC CFLAGS CPPFLAGS LDFLAGS LIBS' >disttest/config.site + cd disttest && CONFIG_SITE=config.site ../$(distdir)/configure + $(MAKE) -C disttest + $(MAKE) -C disttest check + $(MAKE) -C disttest dist + +.PHONY: tags +tags: + rm -f tags + ctags lib/*.c lib/*.h + +TRACKFS = trackfs +trackinstall: + $(TRACKFS) -l install.log -b backup.cpio $(MAKE) install + +# For the justification of the following Makefile rules, see node +# `Automatic Remaking' in GNU Autoconf documentation. + +$(MAINT)$(srcdir)/configure: $(srcdir)/configure.in $(srcdir)/aclocal.m4 + $(RM) $(srcdir)/configure + cd $(srcdir) && autoconf + +$(MAINT)$(srcdir)/config.h.in: $(srcdir)/stamp-h.in +$(MAINT)$(srcdir)/stamp-h.in: $(srcdir)/configure.in $(srcdir)/acconfig.h + $(RM) $(srcdir)/config.h.in + cd $(srcdir) && autoheader + cd $(srcdir) && $(RM) stamp-h.in && echo timestamp > stamp-h.in + +$(MAINT)config.h: stamp-h +$(MAINT)stamp-h: config.h.in config.status + CONFIG_FILES= CONFIG_HEADERS=config.h ./config.status + $(RM) stamp-h && echo timestamp > stamp-h + +$(MAINT)Makefile: Makefile.in config.status + CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status + +$(MAINT)lib/Makefile: lib/Makefile.in config.status + CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status + +$(MAINT)lib/sys_elf.h: lib/stamp-h +$(MAINT)lib/stamp-h: lib/sys_elf.h.in config.status + CONFIG_FILES= CONFIG_HEADERS=lib/sys_elf.h ./config.status + $(RM) lib/stamp-h && echo timestamp > lib/stamp-h + +$(MAINT)po/Makefile: po/Makefile.in config.status + CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status + +$(MAINT)libelf.pc: libelf.pc.in config.status + CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status + +RECHECK_FLAGS = CC='$(CC)' CPPFLAGS='$(CPPFLAGS)' \ + CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' LIBS='$(LIBS)' + +$(MAINT)config.status: configure config.h.in VERSION + $(RECHECK_FLAGS) ./config.status --recheck + +$(MAINT)reconfig: + $(RM) config.cache + $(RECHECK_FLAGS) ./config.status --recheck + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/README Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,310 @@ +This is the public release of libelf-0.8.10, a free ELF object +file access library. If you have problems with applications +that use libelf and work with the commercial (SVR4, Solaris) +version but not with this one, please contact me. + +IMPORTANT NOTE: If you have libelf-0.5.2 installed, you probably +have a file .../include/elf.h that contains the single line +``#include ''. REMOVE THIS FILE BEFORE YOU RUN +configure. + +Installation is straightforward - the package is autoconf'ed. Just do +``cd libelf-0.8.10; ./configure; make; make install''. Header files +will be installed in .../include/libelf/. If your system does not +provide its own versions of libelf.h, nlist.h or gelf.h, ``make +install'' will add the missing headers. If you prefer not to have +these files installed in /usr/include, use ``--disable-compat'' and +add ``-I /usr/include/libelf'' to your CFLAGS when compiling +libelf-based programs. + +Note to distribution makers: You can install libelf in a separate root +hierarchy by using the command ``make instroot=/my/root install''. +You should also use the ``--enable-compat'' configure option in that +case, or run ``make instroot=/my/root install-compat'' manually, to +install all the required header files. + +If you are running Linux with libc 5.* as the default C library, +and you plan to use the 64-bit functions, you must either use +``-I.../include/libelf'', or remove /usr/include/libelf.h and use +``--enable-compat'' when running configure. Libc 6.* (aka glibc2) +doesn't have its own , or . + +You need an ANSI/ISO C compiler to build libelf. Gcc is optimal. + +On some systems (in particular, Solaris and all variants of Linux), +``make'' will try to build a shared library. If you run into problems +on your system, please pass ``--disable-shared'' to configure. +If you build a shared library and want it to be installed as +``libelf-0.8.10.so'' rather than ``libelf.so.0.8.10'', please use +``./configure --enable-gnu-names''. Other files, e.g. ``libelf.so'' and +``libelf.so.0'' are NOT affected. + +Another configure option, ``--enable-debug'', adds debugging code to +libelf; if you don't run into problems, you will probably not need it. + +When creating an ELF shared library, it is possible to add references +to other shared libraries in the DYNAMIC section of the resulting +file. The make variable DEPSHLIBS contains a list of libraries to add. +It is set to ``-lc'' on Linux systems, and empty otherwise. To +override this setting, use something like ``make DEPSHLIBS="-la -lb"''. +For Linux, `-lc' is included automagically. + +NLS is available and enabled by default. To turn it off, pass the +``--disable-nls'' option to configure. + +Libelf can use gettext or catgets for accessing message +catalogs. If gettext is available AND is part of libc (i.e. not +in a separate library), it will be used. Otherwise, configure +will look for catgets. If you have gettext in a separate +library and want to use it, you should pass the library's name +to configure, e.g. ``LIBS=-lintl ./configure''. Note that you +MUST link your libelf-based applications with -lintl then, +which is probably not what you want, or change the DEPSHLIBS variable +described above (in case you're building a shared library). + +If you have GNU gettext 0.10 installed on your system, and if GNU gettext +runs on top of the catgets interface (rather old Linux systems, using +libc5), configure will refuse to use it and use catgets instead. If you +absolutely want to use GNU gettext, go ahead and rebuild it (which is +IMHO a good idea in general in this case): + + cd .../gettext-0.10 + ac_cv_func_catgets=no ac_cv_func_gettext=no ./configure + make + make install + +After that, return to the libelf build directory, remove +config.cache, and start over. + +*** Large File Support (LFS) applications *** + +Some 32-bit systems support files that are larger than the address space +of the architecture. On these, the `off_t' data type may have 32 or +64 bits, depending on the API you choose. Since off_t is also part of +the libelf API, in particular the Elf_Data and Elf_Arhdr structures, +an application compiled with large file support will need a version of +libelf that has also been compiled with LFS; otherwise, it won't work +correctly. Similarly, a program compiled without LFS needs a library +compiled without LFS. + +Note that libelf is currently unable to process large files on 32-bit +architectures, whether you compile it for LFS or not, for the simple +reason that the files won't fit into the processes' address space. +Therefore, libelf is compiled without LFS by default. It can of course +read and write ELF files for 64-bit architectures, but they will be +limited in length on a 32-bit system. + +You may compile libelf with large file support by setting CPPFLAGS at +configuration time: + + CPPFLAGS=`getconf LFS_CFLAGS` ./configure + +But I really, really recommend you don't, because it breaks binary +compatibility with existing libelf based applications. + +*** 64-bit support *** + +Starting with libelf-0.7.0, libelf also supports 64-bit ELF files. +This is enabled by default unless your system (or your compiler) does +not support 64-bit integers, or lacks 64-bit declarations in . +If you have problems building with 64-bit support, please do + + ./configure --disable-elf64 + +for the moment, and contact me. Please note that I haven't tested 64-bit +support much. There are still some unresolved problems, e.g. IRIX +uses different Elf64_Rel and Elf64_Rela structures (they replaced the +r_info member), and the enumeration values for Elf_Type differ from +the commercial (SVR4) implementation of libelf - they broke binary +compatibility for no good reason, and I'm not willing to follow their +footsteps. The result is that libelf-0.7.* ist upward compatible with +libelf-0.6.4 (as it should be) but INCOMPATIBLE WITH SVR4 LIBELF. If you +have both versions installed, you'd better make sure that you link with +the library that matches the you're #include'ing. + +*** Symbol Versioning *** + +Libelf >= 0.8.0 supports the data structures and definitions used for +symbol versioning on Solaris and Linux, in particular, the Elfxx_Verdef, +Elfxx_Verdaux, Elfxx_Verneed, Elfxx_Vernaux and Elfxx_Versym structures +and the SHT_XXX_verdef, SHT_XXX_verneed and SHT_XXX_versym section types +(where `xx' is either `32' or `64', and `XXX' is either `SUNW' or `GNU'). +Libelf now translates versioning sections to/from their external +representation properly (earlier versions left them in `raw' format, +with the data type set to ELF_T_BYTE). This may cause problems on +systems which use the same (OS-specific) section types for different +purposes. The configure program tries to figure out if your OS uses +versioning; if that check fails, you can use + + ./configure --disable-versioning + +to turn off versioning translation support. + +*** W32 Support *** + +There is now some support for building on W32 systems (requires Microsoft +VC++). In order to build a W32 DLL, cd into the `lib' subdirectory, edit +build.bat if necessary (it needs the path to your compiler binaries) and +run it. If you're lucky, libelf.dll and the import/export libraries will +be built. If not, please drop me a line. + +I tested it on XP Pro (SP2), using VC++ 2005 Express Edition. +Apparently, Visual Studio .NET 2003 works fine as well. + +Various notes regarding the W32 port: + + - When you open() an ELF file, remember to use the O_BINARY flag. + - You may have to add /MD to the linker command line. + +*** Missing things *** + + * There is no documentation. You can use the Solaris + manpages instead (available at http://docs.sun.com/). + The ELF file format is described in several places; + among them Suns "Linker and Libraries Guide" and the + "System V Application Binary Interface" documents; + http://www.caldera.com/developer/devspecs/gabi41.pdf and + http://www.caldera.com/developer/gabi/ are probably good + starting points. Processor-specific documentation is spread + across a number of `Processor Supplement' documents, one + for each architecture; you'll have to use a search engine to + find them. + + * The COFF file format is not understood. This is so obsolete + that it will probably never be implemented. + + * nlist(3) is incomplete; the n_type and n_sclass + members of struct nl are set to zero even if type + (that is, debug) information is available. + + * Libelf does not translate Solaris' `Move' and `Syminfo' + sections. You can read them using elf_getdata(), but you'll + only get raw (untranslated) bytes. + +Changes since 0.8.9: + + * Ported to QNX Neutrino. + * Fixed Windows build errors. + * Parallel (make -j) installation should work now. + + * It's now possible to enable and disable select sanity checks + libelf performs. Currently, this affects the "NUL terminated + string table entry" check performed in elf_strptr(). By + default, the function will return an error if the string + requested is not properly terminated - because some + applications might dump core otherwise. If you configure + libelf with `--disable-sanity-checks', however, the check + (and, in the future, probably others as well) is disabled + by default. You can still turn it on and off at runtime by + setting the LIBELF_SANITY_CHECKS environment variable to + an integer value: + + # disable all sanity checks + export LIBELF_SANITY_CHECKS=0 + + # enable all sanity checks + export LIBELF_SANITY_CHECKS=-1 + + Each bit of the value corresponds to a particular check, + so you could use LIBELF_SANITY_CHECKS=1 to enable only + the elf_strptr() check. You may also use a value in hex + (0x...) or octal (0...) format. + +Changes since 0.8.8: + + * Improved translator for symbol versioning sections. + * The W32 library is now built in the `lib' subdirectory. + * Windows DLLs should work now. + +Changes since 0.8.6: + + * added elf_getphnum(). + * added elf_getshnum(). + * added elf_getshstrndx(). + * added elfx_update_shstrndx(). + * handle interrupted reads/writes more gracefully. + * added (partial) support for unusual e_[ps]hentsize values. + * fixed the bugs introduced in 0.8.7. + +Changes since 0.8.5: + + * added W32 support. + * added workaround for alignment errors in archive members. + * my email address has changed again ;) + +Changes since 0.8.4: + + * elf_strptr() should now work more safely with fragmented + or badly formatted string tables. + +Changes since 0.8.3: + + * Fixed a bug in elf_update() that was introduced in 0.8.3. + +Changes since 0.8.2: + + * Should compile on MacOSX now. + + * Can read and write files with more than 65280 sections + + * Tries to handle 64-bit ELF files that use 8-byte hash table + entries. In particular, libelf tries to guess the data type in + elf_getdata(), and doesn't override sh_entsize in elf_update() + any longer. If you want the library to pick the entry size, + you must set its value to 0 before you call elf_update(). + + * No longer dumps core in elf_update() when a versioning section + has no data. Instead, it returns an error message. Note that + you're supposed to provide a valid d_buf for any section, unless + it's empty or has SHT_NOBITS type. + + * Building a shared library is now the default (if supported). + +Changes since 0.8.0: + + * Corrected typo in lib/{32,64}.xlatetof.c that sometimes + caused a compilation failure. + + * Use open(name, O_RDONLY|O_BINARY) in lib/nlist.c. + +Changes since 0.7.0: + + * I implemented the gelf_* interface, as found on Solaris. + I don't know whether it's compatible -- the Solaris manpage + isn't very specific, so I had to guess return values etc. in + some cases. + + * Added elf{32,64}_checksum (supposed to be compatible with + Solaris). + + * Added symbol versioning support. + +Changes since 0.6.4: + + * Fixed configure for IRIX systems + * Added check for truncated archive members + * Added check for misaligned SHDR/PHDR tables + * Support for building libelf together with GNU libc + * Added elf_memory(3) + * Added 64-bit support + +Changes since 0.5.2: + + * some bug fixes + * mmap support + * new directory layout + * There is a new function, elf_delscn(), that deletes + a section from an ELF file. It also adjusts the + sh_link and sh_info members in the section header + table, if (and ONLY if) the ELF standard indicates + that these values are section indices. References + to the deleted section will be cleared, so be careful. + * my email address has changed ;) + +Where to get libelf: + + ftp://ftp.ibiblio.org/pub/Linux/libs/ + http://www.mr511.de/software/ + +Michael "Tired" Riepe + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/VERSION --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/VERSION Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1 @@ +0.8.10 diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/acconfig.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/acconfig.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,89 @@ +/* + * acconfig.h - Special definitions for libelf, processed by autoheader. + * Copyright (C) 1995 - 2001, 2004, 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* @(#) $Id: acconfig.h,v 1.15 2007/09/07 12:07:59 michael Exp $ */ + +/* Define if you want to include extra debugging code */ +#undef ENABLE_DEBUG + +/* Define if you want to support extended ELF formats */ +#undef ENABLE_EXTENDED_FORMAT + +/* Define if you want ELF format sanity checks by default */ +#undef ENABLE_SANITY_CHECKS + +/* Define if memmove() does not copy overlapping arrays correctly */ +#undef HAVE_BROKEN_MEMMOVE + +/* Define if you have the catgets function. */ +#undef HAVE_CATGETS + +/* Define if you have the dgettext function. */ +#undef HAVE_DGETTEXT + +/* Define if you have the memset function. */ +#undef HAVE_MEMSET + +/* Define if struct nlist is declared in or */ +#undef HAVE_STRUCT_NLIST_DECLARATION + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_LINK_H + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_SYS_LINK_H + +/* Define to `' or `' if one of them is present */ +#undef __LIBELF_HEADER_ELF_H + +/* Define if you want 64-bit support (and your system supports it) */ +#undef __LIBELF64 + +/* Define if you want 64-bit support, and are running IRIX */ +#undef __LIBELF64_IRIX + +/* Define if you want 64-bit support, and are running Linux */ +#undef __LIBELF64_LINUX + +/* Define if you want symbol versioning (and your system supports it) */ +#undef __LIBELF_SYMBOL_VERSIONS + +/* Define if symbol versioning uses Sun section type (SHT_SUNW_*) */ +#undef __LIBELF_SUN_SYMBOL_VERSIONS + +/* Define if symbol versioning uses GNU section types (SHT_GNU_*) */ +#undef __LIBELF_GNU_SYMBOL_VERSIONS + +/* Define to a 64-bit signed integer type if one exists */ +#undef __libelf_i64_t + +/* Define to a 64-bit unsigned integer type if one exists */ +#undef __libelf_u64_t + +/* Define to a 32-bit signed integer type if one exists */ +#undef __libelf_i32_t + +/* Define to a 32-bit unsigned integer type if one exists */ +#undef __libelf_u32_t + +/* Define to a 16-bit signed integer type if one exists */ +#undef __libelf_i16_t + +/* Define to a 16-bit unsigned integer type if one exists */ +#undef __libelf_u16_t diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/aclocal.m4 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/aclocal.m4 Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,336 @@ +# aclocal.m4 - Local additions to Autoconf macros. +# Copyright (C) 1995 - 2006 Michael Riepe +# +# This library 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 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# @(#) $Id: aclocal.m4,v 1.27 2007/09/07 12:07:59 michael Exp $ + +AC_PREREQ(2.13) + +dnl mr_PACKAGE(package-name) +AC_DEFUN(mr_PACKAGE, [changequote(<<, >>)dnl + changequote([, ])dnl + PACKAGE=$1 + VERSION=`cat $srcdir/VERSION` + AC_SUBST(PACKAGE) + AC_SUBST(VERSION) + AC_ARG_ENABLE(maintainer-mode, + [ --enable-maintainer-mode + enable maintainer-specific make rules (default: auto)], + [mr_enable_maintainer_mode="$enableval"], + [case :${I_AM_THE_MAINTAINER_OF}: in + *:$1:*) mr_enable_maintainer_mode=yes;; + *) mr_enable_maintainer_mode=no;; + esac]) + if test x"$mr_enable_maintainer_mode" = x"yes"; then + MAINT= + else + MAINT='maintainer-only-' + fi + AC_SUBST(MAINT) +]) + +AC_DEFUN(mr_ENABLE_NLS, [ + AC_PROVIDE([$0]) + + # Needed for `make dist' even if NLS is disabled. + GMOFILES= + MSGFILES= + POFILES= + for mr_lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $mr_lang.gmo" + MSGFILES="$MSGFILES $mr_lang.msg" + POFILES="$POFILES $mr_lang.po" + done + AC_SUBST(GMOFILES) + AC_SUBST(MSGFILES) + AC_SUBST(POFILES) + + AC_MSG_CHECKING([whether NLS is requested]) + AC_ARG_ENABLE(nls, + [ --enable-nls use Native Language Support (default: yes)], + [mr_enable_nls="$enableval"], + [mr_enable_nls=yes]) + AC_MSG_RESULT($mr_enable_nls) + + CATOBJEXT= + INSTOBJEXT= + localedir= + if test "$mr_enable_nls" = yes; then + mr_PATH=`echo ":$PATH" | sed -e 's,:[^:]*openwin[^:]*,,g' -e 's,^:,,'` + AC_CACHE_CHECK([for dgettext], + mr_cv_func_dgettext, [ + AC_TRY_LINK([#include ], + [char *s = dgettext("", ""); return 0], + [mr_cv_func_dgettext=yes], + [mr_cv_func_dgettext=no]) + ]) + if test "$mr_cv_func_dgettext" = yes; then + AC_PATH_PROG(MSGFMT, msgfmt, no, $mr_PATH) + if test "$MSGFMT" != no; then + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT, $mr_PATH) + AC_PATH_PROG(XGETTEXT, xgettext, xgettext, $mr_PATH) + AC_PATH_PROG(MSGMERGE, msgmerge, msgmerge, $mr_PATH) + AC_CACHE_CHECK([for GNU gettext], + mr_cv_gnu_gettext, [ + AC_TRY_LINK([], + [extern int _nl_msg_cat_cntr; return _nl_msg_cat_cntr], + [mr_cv_gnu_gettext=yes], + [mr_cv_gnu_gettext=no]) + ]) + if test "$mr_cv_gnu_gettext" = yes; then + AC_CACHE_CHECK([for losing catgets-based GNU gettext], + mr_cv_catgets_based_gettext, [ + AC_TRY_LINK([], + [extern int _msg_tbl_length; return _msg_tbl_length], + [mr_cv_catgets_based_gettext=yes], + [mr_cv_catgets_based_gettext=no]) + ]) + if test "$mr_cv_catgets_based_gettext" = yes; then + # This loses completely. Turn it off and use catgets. + LIBS=`echo $LIBS | sed 's,-lintl,,g'` + mr_cv_func_dgettext=no + else + # Is there a better test for this case? + AC_CACHE_CHECK([for pure GNU gettext], + mr_cv_pure_gnu_gettext, [ + AC_TRY_LINK([], + [extern int gettext(); return gettext()], + [mr_cv_pure_gnu_gettext=yes], + [mr_cv_pure_gnu_gettext=no]) + ]) + if test "$mr_cv_pure_gnu_gettext" = yes; then + CATOBJEXT=.gmo + localedir='$(prefix)/share/locale' + else + CATOBJEXT=.mo + localedir='$(prefix)/lib/locale' + fi + INSTOBJEXT=.mo + fi + else + # System provided gettext + CATOBJEXT=.mo + INSTOBJEXT=.mo + localedir='$(prefix)/lib/locale' + fi + else + # Gettext but no msgfmt. Try catgets. + mr_cv_func_dgettext=no + fi + fi + if test "$mr_cv_func_dgettext" = yes; then + AC_DEFINE(HAVE_DGETTEXT) + else + AC_CACHE_CHECK([for catgets], mr_cv_func_catgets, [ + AC_TRY_LINK([#include ], + [catgets(catopen("",0),0,0,"");return 0;], + [mr_cv_func_catgets=yes], + [mr_cv_func_catgets=no]) + ]) + if test "$mr_cv_func_catgets" = yes; then + AC_PATH_PROG(GENCAT, gencat, no, $mr_PATH) + if test "$GENCAT" != no; then + AC_DEFINE(HAVE_CATGETS) + AC_PATH_PROG(GMSGFMT, [gmsgfmt msgfmt], msgfmt, $mr_PATH) + AC_PATH_PROG(XGETTEXT, xgettext, xgettext, $mr_PATH) + CATOBJEXT=.cat + INSTOBJEXT=.cat + localedir='$(prefix)/lib/locale' + fi + else + AC_MSG_WARN([no NLS support, disabled]) + mr_enable_nls=no + fi + fi + fi + AC_SUBST(CATOBJEXT) + AC_SUBST(INSTOBJEXT) + AC_SUBST(localedir) + + POSUB= + CATALOGS= + if test "$mr_enable_nls" = yes; then + AC_MSG_CHECKING([for catalogs to be installed]) + mr_linguas= + for mr_lang in ${LINGUAS=$ALL_LINGUAS}; do + case " $ALL_LINGUAS " in + *" $mr_lang "*) + mr_linguas="$mr_linguas$mr_lang " + CATALOGS="$CATALOGS $mr_lang$CATOBJEXT" + ;; + esac + done + AC_MSG_RESULT($mr_linguas) + POSUB=po + fi + AC_SUBST(CATALOGS) + AC_SUBST(POSUB) +]) + +AC_DEFUN(mr_TARGET_ELF, [ + AC_PROVIDE([$0]) + AC_CACHE_CHECK([for native ELF system], + mr_cv_target_elf, + [AC_TRY_RUN(changequote(<<, >>)dnl +<<#include +int +main(int argc, char **argv) { + char buf[BUFSIZ]; + FILE *fp; + int n; + + if ((fp = fopen(*argv, "r")) == NULL) { + exit(1); + } + n = fread(buf, 1, sizeof(buf), fp); + if (n >= 52 + && buf[0] == '\177' + && buf[1] == 'E' + && buf[2] == 'L' + && buf[3] == 'F') { + exit(0); + } + exit(1); +}>>, changequote([, ])dnl + mr_cv_target_elf=yes, + mr_cv_target_elf=no, + mr_cv_target_elf=no)])]) + +AC_DEFUN(mr_ENABLE_SHARED, [ + AC_PROVIDE([$0]) + PICFLAGS= + SHLIB_SFX= + SHLINK_SFX= + SONAME_SFX= + LINK_SHLIB= + INSTALL_SHLIB= + DEPSHLIBS= + AC_MSG_CHECKING([whether to build a shared library]) + AC_ARG_ENABLE(shared, + [ --enable-shared build shared library (default: yes)], + [mr_enable_shared="$enableval"], + [mr_enable_shared=yes]) + AC_MSG_RESULT($mr_enable_shared) + if test "$mr_enable_shared" = yes; then + AC_MSG_CHECKING([whether GNU naming conventions are requested]) + AC_ARG_ENABLE(gnu-names, + [ --enable-gnu-names use GNU library naming conventions (default: no)], + [mr_enable_gnu_names="$enableval"], + [mr_enable_gnu_names=no]) + AC_MSG_RESULT($mr_enable_gnu_names) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_PROG_CC]) + AC_PATH_PROG(LD, ld, ld) + case "$host" in + *-linux*|*-gnu*) + if test "$GCC" = yes; then + mr_TARGET_ELF + if test "$mr_cv_target_elf" = yes; then + PICFLAGS='-fPIC -DPIC' + if test "$mr_enable_gnu_names" = yes + then SHLIB_SFX='-$(VERSION).so' + else SHLIB_SFX='.so.$(VERSION)' + fi + SHLINK_SFX='.so' + SONAME_SFX='.so.$(MAJOR)' + LINK_SHLIB='$(CC) -shared -Wl,-soname,$(SONAME)' + INSTALL_SHLIB='$(INSTALL_PROGRAM)' + DEPSHLIBS='-lc' + else + AC_MSG_WARN([shared libraries not supported for $host]) + mr_enable_shared=no + fi + elif ${CC} -V 2>&1 | grep 'Intel(R) C++ Compiler' >/dev/null 2>&1; then + AC_MSG_WARN([Use --disable-shared if $CC fails to build the shared library]) + PICFLAGS='-fPIC -DPIC' + if test "$mr_enable_gnu_names" = yes + then SHLIB_SFX='-$(VERSION).so' + else SHLIB_SFX='.so.$(VERSION)' + fi + SHLINK_SFX='.so' + SONAME_SFX='.so.$(MAJOR)' + LINK_SHLIB='$(CC) -shared -Wl,-soname,$(SONAME)' + INSTALL_SHLIB='$(INSTALL_PROGRAM)' + DEPSHLIBS='-lc' + else + AC_MSG_WARN([GNU CC required for building shared libraries]) + mr_enable_shared=no + fi + ;; + i386-pc-nto-qnx*) + mr_TARGET_ELF + if test "$mr_cv_target_elf" = yes; then + PICFLAGS='-fPIC -DPIC' + if test "$mr_enable_gnu_names" = yes + then SHLIB_SFX='-$(VERSION).so' + else SHLIB_SFX='.so.$(VERSION)' + fi + SHLINK_SFX='.so' + SONAME_SFX='.so.$(MAJOR)' + LINK_SHLIB='$(CC) -shared -Wl,-soname,$(SONAME)' + INSTALL_SHLIB='$(INSTALL_PROGRAM)' + DEPSHLIBS='-lc' + else + AC_MSG_WARN([shared libraries not supported for $host]) + mr_enable_shared=no + fi + ;; + sparc-sun-solaris2*) + if test "$GCC" = yes; then + PICFLAGS='-fPIC -DPIC' + else + PICFLAGS='-K PIC -DPIC' + fi + if test "$mr_enable_gnu_names" = yes + then SHLIB_SFX='-$(MAJOR).so' + else SHLIB_SFX='.so.$(MAJOR)' + fi + SONAME_SFX='.so.$(MAJOR)' + SHLINK_SFX='.so' + LINK_SHLIB='$(LD) -G -z text -h $(SONAME)' + INSTALL_SHLIB='$(INSTALL_PROGRAM)' + ;; + *) + AC_MSG_WARN([shared libraries not supported for $host]) + mr_enable_shared=no + ;; + esac + else + mr_enable_shared=no + fi + AC_SUBST(PICFLAGS) + AC_SUBST(SHLIB_SFX) + AC_SUBST(SHLINK_SFX) + AC_SUBST(SONAME_SFX) + AC_SUBST(LINK_SHLIB) + AC_SUBST(INSTALL_SHLIB) + AC_SUBST(DEPSHLIBS) + DO_SHLIB="$mr_enable_shared" + AC_SUBST(DO_SHLIB) +]) + +AC_DEFUN(mr_ENABLE_DEBUG, [ + AC_PROVIDE([$0]) + AC_ARG_ENABLE(debug, + [ --enable-debug include extra debugging code (default: no)], + [mr_enable_debug="$enableval"], + [mr_enable_debug=no]) + if test "$mr_enable_debug" = yes; then + AC_DEFINE(ENABLE_DEBUG) + fi +]) + +# vi: set ts=8 sw=2 : diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/config.guess --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/config.guess Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1459 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2004-06-11' + +# 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 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amd64:OpenBSD:*:*) + echo x86_64-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + cats:OpenBSD:*:*) + echo arm-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + luna88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit 0 ;; + macppc:MirBSD:*:*) + echo powerppc-unknown-mirbsd${UNAME_RELEASE} + exit 0 ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha*:OpenVMS:*:*) + echo alpha-hp-vms + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + # GNU/KFreeBSD systems have a "k" prefix to indicate we are using + # FreeBSD's kernel, but not the complete OS. + case ${LIBC} in gnu) kernel_only='k' ;; esac + echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + case `uname -p` in + *86) UNAME_PROCESSOR=i686 ;; + powerpc) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit 0 ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/config.h.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/config.h.in Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,151 @@ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define to `long' if doesn't define. */ +#undef off_t + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you want to include extra debugging code */ +#undef ENABLE_DEBUG + +/* Define if you want to support extended ELF formats */ +#undef ENABLE_EXTENDED_FORMAT + +/* Define if you want ELF format sanity checks by default */ +#undef ENABLE_SANITY_CHECKS + +/* Define if memmove() does not copy overlapping arrays correctly */ +#undef HAVE_BROKEN_MEMMOVE + +/* Define if you have the catgets function. */ +#undef HAVE_CATGETS + +/* Define if you have the dgettext function. */ +#undef HAVE_DGETTEXT + +/* Define if you have the memset function. */ +#undef HAVE_MEMSET + +/* Define if struct nlist is declared in or */ +#undef HAVE_STRUCT_NLIST_DECLARATION + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_LINK_H + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_SYS_LINK_H + +/* Define to `' or `' if one of them is present */ +#undef __LIBELF_HEADER_ELF_H + +/* Define if you want 64-bit support (and your system supports it) */ +#undef __LIBELF64 + +/* Define if you want 64-bit support, and are running IRIX */ +#undef __LIBELF64_IRIX + +/* Define if you want 64-bit support, and are running Linux */ +#undef __LIBELF64_LINUX + +/* Define if you want symbol versioning (and your system supports it) */ +#undef __LIBELF_SYMBOL_VERSIONS + +/* Define if symbol versioning uses Sun section type (SHT_SUNW_*) */ +#undef __LIBELF_SUN_SYMBOL_VERSIONS + +/* Define if symbol versioning uses GNU section types (SHT_GNU_*) */ +#undef __LIBELF_GNU_SYMBOL_VERSIONS + +/* Define to a 64-bit signed integer type if one exists */ +#undef __libelf_i64_t + +/* Define to a 64-bit unsigned integer type if one exists */ +#undef __libelf_u64_t + +/* Define to a 32-bit signed integer type if one exists */ +#undef __libelf_i32_t + +/* Define to a 32-bit unsigned integer type if one exists */ +#undef __libelf_u32_t + +/* Define to a 16-bit signed integer type if one exists */ +#undef __libelf_i16_t + +/* Define to a 16-bit unsigned integer type if one exists */ +#undef __libelf_u16_t + +/* The number of bytes in a __int64. */ +#undef SIZEOF___INT64 + +/* The number of bytes in a int. */ +#undef SIZEOF_INT + +/* The number of bytes in a long. */ +#undef SIZEOF_LONG + +/* The number of bytes in a long long. */ +#undef SIZEOF_LONG_LONG + +/* The number of bytes in a short. */ +#undef SIZEOF_SHORT + +/* Define if you have the ftruncate function. */ +#undef HAVE_FTRUNCATE + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcmp function. */ +#undef HAVE_MEMCMP + +/* Define if you have the memcpy function. */ +#undef HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#undef HAVE_MEMMOVE + +/* Define if you have the memset function. */ +#undef HAVE_MEMSET + +/* Define if you have the header file. */ +#undef HAVE_AR_H + +/* Define if you have the header file. */ +#undef HAVE_ELF_H + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_GELF_H + +/* Define if you have the header file. */ +#undef HAVE_LIBELF_H + +/* Define if you have the header file. */ +#undef HAVE_LINK_H + +/* Define if you have the header file. */ +#undef HAVE_NLIST_H + +/* Define if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_ELF_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_LINK_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/config.sub --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/config.sub Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1549 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2004-03-12' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# 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 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. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ + kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32r | m32rle | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | msp430-* \ + | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nv1) + basic_machine=nv1-cray + os=-unicosmp + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/configure --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/configure Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,3910 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-maintainer-mode + enable maintainer-specific make rules (default: auto)" +ac_help="$ac_help + --enable-compat install , and (default: auto)" +ac_help="$ac_help + --enable-elf64 compile in 64-bit support (default: auto)" +ac_help="$ac_help + --enable-versioning compile in versioning support (default: auto)" +ac_help="$ac_help + --enable-nls use Native Language Support (default: yes)" +ac_help="$ac_help + --enable-shared build shared library (default: yes)" +ac_help="$ac_help + --enable-gnu-names use GNU library naming conventions (default: no)" +ac_help="$ac_help + --enable-extended-format support extended file formats (default: no)" +ac_help="$ac_help + --enable-sanity-checks enable sanity checks by default (default: yes)" +ac_help="$ac_help + --enable-debug include extra debugging code (default: no)" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=VERSION + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + + + + + PACKAGE=libelf + VERSION=`cat $srcdir/VERSION` + + + # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + mr_enable_maintainer_mode="$enableval" +else + case :${I_AM_THE_MAINTAINER_OF}: in + *:libelf:*) mr_enable_maintainer_mode=yes;; + *) mr_enable_maintainer_mode=no;; + esac +fi + + if test x"$mr_enable_maintainer_mode" = x"yes"; then + MAINT= + else + MAINT='maintainer-only-' + fi + + + +ALL_LINGUAS=`cd $srcdir/po && echo *.po | sed 's/\.po//g'` + +set `echo $VERSION | sed 's/\./ /g'` +MAJOR=${1-1} +MINOR=${2-0} +PATCH=${3-0} + + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:582: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:611: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:641: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:692: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:724: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 735 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:740: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:766: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:771: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:799: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:831: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:852: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:869: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:886: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:941: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:996: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:1024: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:1047: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#include +#include +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1060: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext < +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:1127: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +for ac_hdr in unistd.h stdint.h fcntl.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1154: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1164: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +for ac_hdr in elf.h sys/elf.h link.h sys/link.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1194: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1204: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +echo $ac_n "checking if ${CC} can compile elf.h""... $ac_c" 1>&6 +echo "configure:1231: checking if ${CC} can compile elf.h" >&5 +if eval "test \"`echo '$''{'libelf_cv_elf_h_works'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + #elif HAVE_SYS_ELF_H + #include + #endif +int main() { +Elf32_Ehdr dummy +; return 0; } +EOF +if { (eval echo configure:1248: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + libelf_cv_elf_h_works=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + libelf_cv_elf_h_works=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$libelf_cv_elf_h_works" 1>&6 +if test "$libelf_cv_elf_h_works" = no; then + ac_cv_header_elf_h=no + ac_cv_header_sys_elf_h=no +fi +if test "$ac_cv_header_elf_h" = yes; then + cat >> confdefs.h <<\EOF +#define __LIBELF_HEADER_ELF_H +EOF + +elif test "$ac_cv_header_sys_elf_h" = yes; then + cat >> confdefs.h <<\EOF +#define __LIBELF_HEADER_ELF_H +EOF + +fi + +for ac_hdr in ar.h libelf.h nlist.h gelf.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1282: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1292: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +echo $ac_n "checking whether to install , and ""... $ac_c" 1>&6 +echo "configure:1319: checking whether to install , and " >&5 +# Check whether --enable-compat or --disable-compat was given. +if test "${enable_compat+set}" = set; then + enableval="$enable_compat" + DO_COMPAT="$enableval" +else + if test "$ac_cv_header_libelf_h$ac_cv_header_nlist_h$ac_cv_header_gelf_h" = yesyesyes + then DO_COMPAT=no + else DO_COMPAT=yes + fi +fi + +echo "$ac_t""$DO_COMPAT" 1>&6 + + +echo $ac_n "checking for working const""... $ac_c" 1>&6 +echo "configure:1335: checking for working const" >&5 +if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if { (eval echo configure:1389: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_const=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_c_const" 1>&6 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +EOF + +fi + +echo $ac_n "checking for off_t""... $ac_c" 1>&6 +echo "configure:1410: checking for off_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#if STDC_HEADERS +#include +#include +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_off_t=yes +else + rm -rf conftest* + ac_cv_type_off_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_off_t" 1>&6 +if test $ac_cv_type_off_t = no; then + cat >> confdefs.h <<\EOF +#define off_t long +EOF + +fi + +echo $ac_n "checking for size_t""... $ac_c" 1>&6 +echo "configure:1443: checking for size_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#if STDC_HEADERS +#include +#include +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_size_t=yes +else + rm -rf conftest* + ac_cv_type_size_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_size_t" 1>&6 +if test $ac_cv_type_size_t = no; then + cat >> confdefs.h <<\EOF +#define size_t unsigned +EOF + +fi + + +echo $ac_n "checking size of short""... $ac_c" 1>&6 +echo "configure:1477: checking size of short" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_short=2 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(short)); + exit(0); +} +EOF +if { (eval echo configure:1496: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_short=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_short=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_short" 1>&6 +cat >> confdefs.h <&6 +echo "configure:1516: checking size of int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_int=4 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(int)); + exit(0); +} +EOF +if { (eval echo configure:1535: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_int" 1>&6 +cat >> confdefs.h <&6 +echo "configure:1555: checking size of long" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_long=4 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(long)); + exit(0); +} +EOF +if { (eval echo configure:1574: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_long=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_long=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_long" 1>&6 +cat >> confdefs.h <&6 +echo "configure:1594: checking size of long long" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_long_long=0 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(long long)); + exit(0); +} +EOF +if { (eval echo configure:1613: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_long_long=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_long_long=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_long_long" 1>&6 +cat >> confdefs.h <&6 +echo "configure:1634: checking size of __int64" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof___int64'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof___int64=0 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(__int64)); + exit(0); +} +EOF +if { (eval echo configure:1653: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof___int64=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof___int64=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof___int64" 1>&6 +cat >> confdefs.h <. + # QNX declares Elf32_Dyn in . + echo $ac_n "checking for struct Elf32_Dyn""... $ac_c" 1>&6 +echo "configure:1679: checking for struct Elf32_Dyn" >&5 +if eval "test \"`echo '$''{'libelf_cv_struct_elf32_dyn'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + libelf_cv_struct_elf32_dyn=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cat > conftest.$ac_ext < +int main() { +Elf32_Dyn x +; return 0; } +EOF +if { (eval echo configure:1707: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + libelf_cv_struct_elf32_dyn=link.h +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cat > conftest.$ac_ext < +int main() { +Elf32_Dyn x +; return 0; } +EOF +if { (eval echo configure:1722: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + libelf_cv_struct_elf32_dyn=sys/link.h +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + libelf_cv_struct_elf32_dyn=no +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* +fi + +echo "$ac_t""$libelf_cv_struct_elf32_dyn" 1>&6 + if test "$libelf_cv_struct_elf32_dyn" = link.h; then + cat >> confdefs.h <<\EOF +#define __LIBELF_NEED_LINK_H 1 +EOF + + elif test "$libelf_cv_struct_elf32_dyn" = sys/link.h; then + cat >> confdefs.h <<\EOF +#define __LIBELF_NEED_SYS_LINK_H 1 +EOF + + elif test "$libelf_cv_struct_elf32_dyn" = no; then + { echo "configure: error: no declaration for Elf32_Dyn" 1>&2; exit 1; } + fi + + # Linux declares struct nlist in . + echo $ac_n "checking for struct nlist in elf.h""... $ac_c" 1>&6 +echo "configure:1755: checking for struct nlist in elf.h" >&5 +if eval "test \"`echo '$''{'libelf_cv_struct_nlist'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + libelf_cv_struct_nlist=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + libelf_cv_struct_nlist=no +fi +rm -f conftest* +fi + +echo "$ac_t""$libelf_cv_struct_nlist" 1>&6 + if test "$libelf_cv_struct_nlist" = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_STRUCT_NLIST_DECLARATION 1 +EOF + + fi + + # Check for 64-bit data types. + echo $ac_n "checking for struct Elf64_Ehdr""... $ac_c" 1>&6 +echo "configure:1790: checking for struct Elf64_Ehdr" >&5 +if eval "test \"`echo '$''{'libelf_cv_struct_elf64_ehdr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + libelf_cv_struct_elf64_ehdr=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + libelf_cv_struct_elf64_ehdr=no +fi +rm -f conftest* +fi + +echo "$ac_t""$libelf_cv_struct_elf64_ehdr" 1>&6 + + # Linux lacks typedefs for scalar ELF64_* types. + echo $ac_n "checking for Elf64_Addr""... $ac_c" 1>&6 +echo "configure:1818: checking for Elf64_Addr" >&5 +if eval "test \"`echo '$''{'libelf_cv_type_elf64_addr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + libelf_cv_type_elf64_addr=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + libelf_cv_type_elf64_addr=no +fi +rm -f conftest* +fi + +echo "$ac_t""$libelf_cv_type_elf64_addr" 1>&6 + + # IRIX' struct Elf64_Rel is slightly different. Ugh. + echo $ac_n "checking for struct Elf64_Rel""... $ac_c" 1>&6 +echo "configure:1846: checking for struct Elf64_Rel" >&5 +if eval "test \"`echo '$''{'libelf_cv_struct_elf64_rel'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + libelf_cv_struct_elf64_rel=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + libelf_cv_struct_elf64_rel=irix +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + libelf_cv_struct_elf64_rel=no +fi +rm -f conftest* +fi +rm -f conftest* +fi + +echo "$ac_t""$libelf_cv_struct_elf64_rel" 1>&6 + + case "$libelf_cv_struct_elf64_ehdr:\ +$libelf_cv_type_elf64_addr:\ +$libelf_cv_struct_elf64_rel" in + yes:yes:yes) + libelf_64bit=yes;; + yes:yes:irix) + cat >> confdefs.h <<\EOF +#define __LIBELF64_IRIX 1 +EOF + + libelf_64bit=yes;; + yes:no:yes) + cat >> confdefs.h <<\EOF +#define __LIBELF64_LINUX 1 +EOF + + libelf_64bit=yes;; + *) + libelf_64bit=no;; + esac + + # Check for symbol versioning definitions + echo $ac_n "checking for Elf32_Verdef""... $ac_c" 1>&6 +echo "configure:1912: checking for Elf32_Verdef" >&5 +if eval "test \"`echo '$''{'libelf_cv_verdef32'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < /* Solaris wants this */ + #endif +int main() { +struct { + Elf32_Verdef vd; + Elf32_Verdaux vda; + Elf32_Verneed vn; + Elf32_Vernaux vna; + } x +; return 0; } +EOF +if { (eval echo configure:1932: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + libelf_cv_verdef32=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + libelf_cv_verdef32=no +fi +rm -f conftest* +fi + +echo "$ac_t""$libelf_cv_verdef32" 1>&6 + + echo $ac_n "checking for Elf64_Verdef""... $ac_c" 1>&6 +echo "configure:1947: checking for Elf64_Verdef" >&5 +if eval "test \"`echo '$''{'libelf_cv_verdef64'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < /* Solaris wants this */ + #endif +int main() { +struct { + Elf64_Verdef vd; + Elf64_Verdaux vda; + Elf64_Verneed vn; + Elf64_Vernaux vna; + } x +; return 0; } +EOF +if { (eval echo configure:1967: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + libelf_cv_verdef64=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + libelf_cv_verdef64=no +fi +rm -f conftest* +fi + +echo "$ac_t""$libelf_cv_verdef64" 1>&6 + + echo $ac_n "checking for SHT_SUNW_verdef""... $ac_c" 1>&6 +echo "configure:1982: checking for SHT_SUNW_verdef" >&5 +if eval "test \"`echo '$''{'libelf_cv_sun_verdef'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + libelf_cv_sun_verdef=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + libelf_cv_sun_verdef=no +fi +rm -f conftest* +fi + +echo "$ac_t""$libelf_cv_sun_verdef" 1>&6 + + echo $ac_n "checking for SHT_GNU_verdef""... $ac_c" 1>&6 +echo "configure:2009: checking for SHT_GNU_verdef" >&5 +if eval "test \"`echo '$''{'libelf_cv_gnu_verdef'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + libelf_cv_gnu_verdef=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + libelf_cv_gnu_verdef=no +fi +rm -f conftest* +fi + +echo "$ac_t""$libelf_cv_gnu_verdef" 1>&6 +else + # lib/elf_repl.h supports 64-bit + libelf_64bit=yes + + # lib/elf_repl.h supports symbol versioning + libelf_cv_verdef32=yes + libelf_cv_verdef64=yes + libelf_cv_sun_verdef=yes + libelf_cv_gnu_verdef=yes +fi + +echo $ac_n "checking for 64-bit integer""... $ac_c" 1>&6 +echo "configure:2046: checking for 64-bit integer" >&5 +if eval "test \"`echo '$''{'libelf_cv_int64'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + if test "$ac_cv_sizeof_long" = 8; then + libelf_cv_int64='long' + elif test "$ac_cv_sizeof___int64" = 8; then + libelf_cv_int64='__int64' + elif test "$ac_cv_sizeof_long_long" = 8; then + libelf_cv_int64='long long' + else + libelf_cv_int64=no + fi +fi + +echo "$ac_t""$libelf_cv_int64" 1>&6 +if test "$libelf_cv_int64" = no; then + libelf_64bit=no +else + cat >> confdefs.h <> confdefs.h <&6 +echo "configure:2077: checking for 32-bit integer" >&5 +if eval "test \"`echo '$''{'libelf_cv_int32'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + if test "$ac_cv_sizeof_int" = 4; then + libelf_cv_int32='int' + elif test "$ac_cv_sizeof_long" = 4; then + libelf_cv_int32='long' + else + libelf_cv_int32=no + fi +fi + +echo "$ac_t""$libelf_cv_int32" 1>&6 +if test "$libelf_cv_int32" = no; then + { echo "configure: error: neither int nor long is 32-bit" 1>&2; exit 1; } +else + cat >> confdefs.h <> confdefs.h <&6 +echo "configure:2106: checking for 16-bit integer" >&5 +if eval "test \"`echo '$''{'libelf_cv_int16'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + if test "$ac_cv_sizeof_short" = 2; then + libelf_cv_int16='short' + elif test "$ac_cv_sizeof_int" = 2; then + libelf_cv_int16='int' + else + libelf_cv_int16=no + fi +fi + +echo "$ac_t""$libelf_cv_int16" 1>&6 +if test "$libelf_cv_int16" = no; then + { echo "configure: error: neither short nor int is 16-bit" 1>&2; exit 1; } +else + cat >> confdefs.h <> confdefs.h <&6 +echo "configure:2138: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2148: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in getpagesize +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2177: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2205: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +echo $ac_n "checking for working mmap""... $ac_c" 1>&6 +echo "configure:2230: checking for working mmap" >&5 +if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_mmap_fixed_mapped=no +else + cat > conftest.$ac_ext < +#include +#include + +/* This mess was copied from the GNU getpagesize.h. */ +#ifndef HAVE_GETPAGESIZE +# ifdef HAVE_UNISTD_H +# include +# endif + +/* Assume that all systems that can run configure have sys/param.h. */ +# ifndef HAVE_SYS_PARAM_H +# define HAVE_SYS_PARAM_H 1 +# endif + +# ifdef _SC_PAGESIZE +# define getpagesize() sysconf(_SC_PAGESIZE) +# else /* no _SC_PAGESIZE */ +# ifdef HAVE_SYS_PARAM_H +# include +# ifdef EXEC_PAGESIZE +# define getpagesize() EXEC_PAGESIZE +# else /* no EXEC_PAGESIZE */ +# ifdef NBPG +# define getpagesize() NBPG * CLSIZE +# ifndef CLSIZE +# define CLSIZE 1 +# endif /* no CLSIZE */ +# else /* no NBPG */ +# ifdef NBPC +# define getpagesize() NBPC +# else /* no NBPC */ +# ifdef PAGESIZE +# define getpagesize() PAGESIZE +# endif /* PAGESIZE */ +# endif /* no NBPC */ +# endif /* no NBPG */ +# endif /* no EXEC_PAGESIZE */ +# else /* no HAVE_SYS_PARAM_H */ +# define getpagesize() 8192 /* punt totally */ +# endif /* no HAVE_SYS_PARAM_H */ +# endif /* no _SC_PAGESIZE */ + +#endif /* no HAVE_GETPAGESIZE */ + +#ifdef __cplusplus +extern "C" { void *malloc(unsigned); } +#else +char *malloc(); +#endif + +int +main() +{ + char *data, *data2, *data3; + int i, pagesize; + int fd; + + pagesize = getpagesize(); + + /* + * First, make a file with some known garbage in it. + */ + data = malloc(pagesize); + if (!data) + exit(1); + for (i = 0; i < pagesize; ++i) + *(data + i) = rand(); + umask(0); + fd = creat("conftestmmap", 0600); + if (fd < 0) + exit(1); + if (write(fd, data, pagesize) != pagesize) + exit(1); + close(fd); + + /* + * Next, try to mmap the file at a fixed address which + * already has something else allocated at it. If we can, + * also make sure that we see the same garbage. + */ + fd = open("conftestmmap", O_RDWR); + if (fd < 0) + exit(1); + data2 = malloc(2 * pagesize); + if (!data2) + exit(1); + data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1); + if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED, fd, 0L)) + exit(1); + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data2 + i)) + exit(1); + + /* + * Finally, make sure that changes to the mapped area + * do not percolate back to the file as seen by read(). + * (This is a bug on some variants of i386 svr4.0.) + */ + for (i = 0; i < pagesize; ++i) + *(data2 + i) = *(data2 + i) + 1; + data3 = malloc(pagesize); + if (!data3) + exit(1); + if (read(fd, data3, pagesize) != pagesize) + exit(1); + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data3 + i)) + exit(1); + close(fd); + unlink("conftestmmap"); + exit(0); +} + +EOF +if { (eval echo configure:2378: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_func_mmap_fixed_mapped=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_mmap_fixed_mapped=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6 +if test $ac_cv_func_mmap_fixed_mapped = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_MMAP 1 +EOF + +fi + +for ac_func in ftruncate memcmp memcpy memmove +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2403: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2431: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in memset +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2458: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2486: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +LIBOBJS="$LIBOBJS ${ac_func}.${ac_objext}" +fi +done + + +if test "$ac_cv_func_memset" = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_MEMSET 1 +EOF + +fi + +echo $ac_n "checking whether overlapping arrays are copied correctly""... $ac_c" 1>&6 +echo "configure:2520: checking whether overlapping arrays are copied correctly" >&5 +if eval "test \"`echo '$''{'libelf_cv_working_memmove'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + libelf_cv_working_memmove='maybe not' +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + libelf_cv_working_memmove=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + libelf_cv_working_memmove=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$libelf_cv_working_memmove" 1>&6 +if test "$libelf_cv_working_memmove" != yes; then + cat >> confdefs.h <<\EOF +#define HAVE_BROKEN_MEMMOVE 1 +EOF + +fi + +echo $ac_n "checking the coffee machine""... $ac_c" 1>&6 +echo "configure:2568: checking the coffee machine" >&5 +if eval "test \"`echo '$''{'mr_cv_coffee_machine'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + mr_cv_coffee_machine='empty - operator may not work as expected' +fi + +echo "$ac_t""$mr_cv_coffee_machine" 1>&6 + +echo $ac_n "checking whether 64-bit ELF support is sufficient""... $ac_c" 1>&6 +echo "configure:2578: checking whether 64-bit ELF support is sufficient" >&5 +echo "$ac_t""$libelf_64bit" 1>&6 +echo $ac_n "checking whether to include 64-bit support""... $ac_c" 1>&6 +echo "configure:2581: checking whether to include 64-bit support" >&5 +if test "$libelf_64bit" = no; then + libelf_enable_64bit=no +else + # Check whether --enable-elf64 or --disable-elf64 was given. +if test "${enable_elf64+set}" = set; then + enableval="$enable_elf64" + libelf_enable_64bit="$enableval" +else + libelf_enable_64bit=yes +fi + +fi +echo "$ac_t""$libelf_enable_64bit" 1>&6 +if test "$libelf_enable_64bit" = yes; then + cat >> confdefs.h <<\EOF +#define __LIBELF64 1 +EOF + +fi + +echo $ac_n "checking whether versioning support is sufficient""... $ac_c" 1>&6 +echo "configure:2603: checking whether versioning support is sufficient" >&5 +libelf_versioning=no +case "$libelf_enable_64bit:$libelf_cv_verdef32:$libelf_cv_verdef64" in + no:yes:* | yes:yes:yes) + if test "$libelf_cv_sun_verdef" = yes; then + cat >> confdefs.h <<\EOF +#define __LIBELF_SUN_SYMBOL_VERSIONS 1 +EOF + + libelf_versioning=yes + elif test "$libelf_cv_gnu_verdef" = yes; then + cat >> confdefs.h <<\EOF +#define __LIBELF_GNU_SYMBOL_VERSIONS 1 +EOF + + libelf_versioning=yes + fi;; +esac +echo "$ac_t""$libelf_versioning" 1>&6 +echo $ac_n "checking whether to include versioning support""... $ac_c" 1>&6 +echo "configure:2623: checking whether to include versioning support" >&5 +if test "$libelf_versioning" = no; then + libelf_enable_versioning=no +else + # Check whether --enable-versioning or --disable-versioning was given. +if test "${enable_versioning+set}" = set; then + enableval="$enable_versioning" + libelf_enable_versioning="$enableval" +else + libelf_enable_versioning=yes +fi + +fi +echo "$ac_t""$libelf_enable_versioning" 1>&6 +if test "$libelf_enable_versioning" = yes; then + cat >> confdefs.h <<\EOF +#define __LIBELF_SYMBOL_VERSIONS 1 +EOF + +fi + + + + + # Needed for `make dist' even if NLS is disabled. + GMOFILES= + MSGFILES= + POFILES= + for mr_lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $mr_lang.gmo" + MSGFILES="$MSGFILES $mr_lang.msg" + POFILES="$POFILES $mr_lang.po" + done + + + + + echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6 +echo "configure:2661: checking whether NLS is requested" >&5 + # Check whether --enable-nls or --disable-nls was given. +if test "${enable_nls+set}" = set; then + enableval="$enable_nls" + mr_enable_nls="$enableval" +else + mr_enable_nls=yes +fi + + echo "$ac_t""$mr_enable_nls" 1>&6 + + CATOBJEXT= + INSTOBJEXT= + localedir= + if test "$mr_enable_nls" = yes; then + mr_PATH=`echo ":$PATH" | sed -e 's,:^:*openwin^:*,,g' -e 's,^:,,'` + echo $ac_n "checking for dgettext""... $ac_c" 1>&6 +echo "configure:2678: checking for dgettext" >&5 +if eval "test \"`echo '$''{'mr_cv_func_dgettext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { +char *s = dgettext("", ""); return 0 +; return 0; } +EOF +if { (eval echo configure:2691: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + mr_cv_func_dgettext=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + mr_cv_func_dgettext=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$mr_cv_func_dgettext" 1>&6 + if test "$mr_cv_func_dgettext" = yes; then + # Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2709: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$MSGFMT" in + /*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$mr_PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_MSGFMT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test -n "$MSGFMT"; then + echo "$ac_t""$MSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test "$MSGFMT" != no; then + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2746: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GMSGFMT" in + /*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$mr_PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_GMSGFMT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT="$ac_cv_path_GMSGFMT" +if test -n "$GMSGFMT"; then + echo "$ac_t""$GMSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2782: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$XGETTEXT" in + /*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$mr_PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT="xgettext" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test -n "$XGETTEXT"; then + echo "$ac_t""$XGETTEXT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "msgmerge", so it can be a program name with args. +set dummy msgmerge; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2818: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_MSGMERGE'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$MSGMERGE" in + /*) + ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$mr_PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_MSGMERGE="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE="msgmerge" + ;; +esac +fi +MSGMERGE="$ac_cv_path_MSGMERGE" +if test -n "$MSGMERGE"; then + echo "$ac_t""$MSGMERGE" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + echo $ac_n "checking for GNU gettext""... $ac_c" 1>&6 +echo "configure:2852: checking for GNU gettext" >&5 +if eval "test \"`echo '$''{'mr_cv_gnu_gettext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + mr_cv_gnu_gettext=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + mr_cv_gnu_gettext=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$mr_cv_gnu_gettext" 1>&6 + if test "$mr_cv_gnu_gettext" = yes; then + echo $ac_n "checking for losing catgets-based GNU gettext""... $ac_c" 1>&6 +echo "configure:2881: checking for losing catgets-based GNU gettext" >&5 +if eval "test \"`echo '$''{'mr_cv_catgets_based_gettext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + mr_cv_catgets_based_gettext=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + mr_cv_catgets_based_gettext=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$mr_cv_catgets_based_gettext" 1>&6 + if test "$mr_cv_catgets_based_gettext" = yes; then + # This loses completely. Turn it off and use catgets. + LIBS=`echo $LIBS | sed 's,-lintl,,g'` + mr_cv_func_dgettext=no + else + # Is there a better test for this case? + echo $ac_n "checking for pure GNU gettext""... $ac_c" 1>&6 +echo "configure:2915: checking for pure GNU gettext" >&5 +if eval "test \"`echo '$''{'mr_cv_pure_gnu_gettext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + mr_cv_pure_gnu_gettext=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + mr_cv_pure_gnu_gettext=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$mr_cv_pure_gnu_gettext" 1>&6 + if test "$mr_cv_pure_gnu_gettext" = yes; then + CATOBJEXT=.gmo + localedir='$(prefix)/share/locale' + else + CATOBJEXT=.mo + localedir='$(prefix)/lib/locale' + fi + INSTOBJEXT=.mo + fi + else + # System provided gettext + CATOBJEXT=.mo + INSTOBJEXT=.mo + localedir='$(prefix)/lib/locale' + fi + else + # Gettext but no msgfmt. Try catgets. + mr_cv_func_dgettext=no + fi + fi + if test "$mr_cv_func_dgettext" = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_DGETTEXT 1 +EOF + + else + echo $ac_n "checking for catgets""... $ac_c" 1>&6 +echo "configure:2969: checking for catgets" >&5 +if eval "test \"`echo '$''{'mr_cv_func_catgets'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { +catgets(catopen("",0),0,0,"");return 0; +; return 0; } +EOF +if { (eval echo configure:2982: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + mr_cv_func_catgets=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + mr_cv_func_catgets=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$mr_cv_func_catgets" 1>&6 + if test "$mr_cv_func_catgets" = yes; then + # Extract the first word of "gencat", so it can be a program name with args. +set dummy gencat; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:3000: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GENCAT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GENCAT" in + /*) + ac_cv_path_GENCAT="$GENCAT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_GENCAT="$GENCAT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$mr_PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_GENCAT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GENCAT" && ac_cv_path_GENCAT="no" + ;; +esac +fi +GENCAT="$ac_cv_path_GENCAT" +if test -n "$GENCAT"; then + echo "$ac_t""$GENCAT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test "$GENCAT" != no; then + cat >> confdefs.h <<\EOF +#define HAVE_CATGETS 1 +EOF + + # Extract the first word of "gmsgfmt msgfmt", so it can be a program name with args. +set dummy gmsgfmt msgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:3041: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GMSGFMT" in + /*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$mr_PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_GMSGFMT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="msgfmt" + ;; +esac +fi +GMSGFMT="$ac_cv_path_GMSGFMT" +if test -n "$GMSGFMT"; then + echo "$ac_t""$GMSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:3077: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$XGETTEXT" in + /*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$mr_PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT="xgettext" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test -n "$XGETTEXT"; then + echo "$ac_t""$XGETTEXT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + CATOBJEXT=.cat + INSTOBJEXT=.cat + localedir='$(prefix)/lib/locale' + fi + else + echo "configure: warning: no NLS support, disabled" 1>&2 + mr_enable_nls=no + fi + fi + fi + + + + + POSUB= + CATALOGS= + if test "$mr_enable_nls" = yes; then + echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6 +echo "configure:3128: checking for catalogs to be installed" >&5 + mr_linguas= + for mr_lang in ${LINGUAS=$ALL_LINGUAS}; do + case " $ALL_LINGUAS " in + *" $mr_lang "*) + mr_linguas="$mr_linguas$mr_lang " + CATALOGS="$CATALOGS $mr_lang$CATOBJEXT" + ;; + esac + done + echo "$ac_t""$mr_linguas" 1>&6 + POSUB=po + fi + + + +LIBINTL= +echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6 +echo "configure:3146: checking for gettext in -lintl" >&5 +ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lintl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBINTL=-lintl +else + echo "$ac_t""no" 1>&6 +fi + + + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:3194: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + + + + PICFLAGS= + SHLIB_SFX= + SHLINK_SFX= + SONAME_SFX= + LINK_SHLIB= + INSTALL_SHLIB= + DEPSHLIBS= + echo $ac_n "checking whether to build a shared library""... $ac_c" 1>&6 +echo "configure:3224: checking whether to build a shared library" >&5 + # Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + mr_enable_shared="$enableval" +else + mr_enable_shared=yes +fi + + echo "$ac_t""$mr_enable_shared" 1>&6 + if test "$mr_enable_shared" = yes; then + echo $ac_n "checking whether GNU naming conventions are requested""... $ac_c" 1>&6 +echo "configure:3236: checking whether GNU naming conventions are requested" >&5 + # Check whether --enable-gnu-names or --disable-gnu-names was given. +if test "${enable_gnu_names+set}" = set; then + enableval="$enable_gnu_names" + mr_enable_gnu_names="$enableval" +else + mr_enable_gnu_names=no +fi + + echo "$ac_t""$mr_enable_gnu_names" 1>&6 + + + # Extract the first word of "ld", so it can be a program name with args. +set dummy ld; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:3251: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$LD" in + /*) + ac_cv_path_LD="$LD" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_LD="$LD" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_LD="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_LD" && ac_cv_path_LD="ld" + ;; +esac +fi +LD="$ac_cv_path_LD" +if test -n "$LD"; then + echo "$ac_t""$LD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + case "$host" in + *-linux*|*-gnu*) + if test "$GCC" = yes; then + + + echo $ac_n "checking for native ELF system""... $ac_c" 1>&6 +echo "configure:3290: checking for native ELF system" >&5 +if eval "test \"`echo '$''{'mr_cv_target_elf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + mr_cv_target_elf=no +else + cat > conftest.$ac_ext < +int +main(int argc, char **argv) { + char buf[BUFSIZ]; + FILE *fp; + int n; + + if ((fp = fopen(*argv, "r")) == NULL) { + exit(1); + } + n = fread(buf, 1, sizeof(buf), fp); + if (n >= 52 + && buf[0] == '\177' + && buf[1] == 'E' + && buf[2] == 'L' + && buf[3] == 'F') { + exit(0); + } + exit(1); +} +EOF +if { (eval echo configure:3321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + mr_cv_target_elf=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + mr_cv_target_elf=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$mr_cv_target_elf" 1>&6 + if test "$mr_cv_target_elf" = yes; then + PICFLAGS='-fPIC -DPIC' + if test "$mr_enable_gnu_names" = yes + then SHLIB_SFX='-$(VERSION).so' + else SHLIB_SFX='.so.$(VERSION)' + fi + SHLINK_SFX='.so' + SONAME_SFX='.so.$(MAJOR)' + LINK_SHLIB='$(CC) -shared -Wl,-soname,$(SONAME)' + INSTALL_SHLIB='$(INSTALL_PROGRAM)' + DEPSHLIBS='-lc' + else + echo "configure: warning: shared libraries not supported for $host" 1>&2 + mr_enable_shared=no + fi + elif ${CC} -V 2>&1 | grep 'Intel(R) C++ Compiler' >/dev/null 2>&1; then + echo "configure: warning: Use --disable-shared if $CC fails to build the shared library" 1>&2 + PICFLAGS='-fPIC -DPIC' + if test "$mr_enable_gnu_names" = yes + then SHLIB_SFX='-$(VERSION).so' + else SHLIB_SFX='.so.$(VERSION)' + fi + SHLINK_SFX='.so' + SONAME_SFX='.so.$(MAJOR)' + LINK_SHLIB='$(CC) -shared -Wl,-soname,$(SONAME)' + INSTALL_SHLIB='$(INSTALL_PROGRAM)' + DEPSHLIBS='-lc' + else + echo "configure: warning: GNU CC required for building shared libraries" 1>&2 + mr_enable_shared=no + fi + ;; + i386-pc-nto-qnx*) + + + echo $ac_n "checking for native ELF system""... $ac_c" 1>&6 +echo "configure:3372: checking for native ELF system" >&5 +if eval "test \"`echo '$''{'mr_cv_target_elf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + mr_cv_target_elf=no +else + cat > conftest.$ac_ext < +int +main(int argc, char **argv) { + char buf[BUFSIZ]; + FILE *fp; + int n; + + if ((fp = fopen(*argv, "r")) == NULL) { + exit(1); + } + n = fread(buf, 1, sizeof(buf), fp); + if (n >= 52 + && buf[0] == '\177' + && buf[1] == 'E' + && buf[2] == 'L' + && buf[3] == 'F') { + exit(0); + } + exit(1); +} +EOF +if { (eval echo configure:3403: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + mr_cv_target_elf=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + mr_cv_target_elf=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$mr_cv_target_elf" 1>&6 + if test "$mr_cv_target_elf" = yes; then + PICFLAGS='-fPIC -DPIC' + if test "$mr_enable_gnu_names" = yes + then SHLIB_SFX='-$(VERSION).so' + else SHLIB_SFX='.so.$(VERSION)' + fi + SHLINK_SFX='.so' + SONAME_SFX='.so.$(MAJOR)' + LINK_SHLIB='$(CC) -shared -Wl,-soname,$(SONAME)' + INSTALL_SHLIB='$(INSTALL_PROGRAM)' + DEPSHLIBS='-lc' + else + echo "configure: warning: shared libraries not supported for $host" 1>&2 + mr_enable_shared=no + fi + ;; + sparc-sun-solaris2*) + if test "$GCC" = yes; then + PICFLAGS='-fPIC -DPIC' + else + PICFLAGS='-K PIC -DPIC' + fi + if test "$mr_enable_gnu_names" = yes + then SHLIB_SFX='-$(MAJOR).so' + else SHLIB_SFX='.so.$(MAJOR)' + fi + SONAME_SFX='.so.$(MAJOR)' + SHLINK_SFX='.so' + LINK_SHLIB='$(LD) -G -z text -h $(SONAME)' + INSTALL_SHLIB='$(INSTALL_PROGRAM)' + ;; + *) + echo "configure: warning: shared libraries not supported for $host" 1>&2 + mr_enable_shared=no + ;; + esac + else + mr_enable_shared=no + fi + + + + + + + + DO_SHLIB="$mr_enable_shared" + + + +# Check whether --enable-extended-format or --disable-extended-format was given. +if test "${enable_extended_format+set}" = set; then + enableval="$enable_extended_format" + mr_enable_extended_format="$enableval" +else + mr_enable_extended_format=no +fi + +if test "$mr_enable_extended_format" = yes; then + cat >> confdefs.h <<\EOF +#define ENABLE_EXTENDED_FORMAT 1 +EOF + +fi + +# Check whether --enable-sanity-checks or --disable-sanity-checks was given. +if test "${enable_sanity_checks+set}" = set; then + enableval="$enable_sanity_checks" + mr_enable_sanity_checks="$enableval" +else + mr_enable_sanity_checks=yes +fi + +if test "$mr_enable_sanity_checks" = yes; then + cat >> confdefs.h <<\EOF +#define ENABLE_SANITY_CHECKS 1 +EOF + +fi + + + + # Check whether --enable-debug or --disable-debug was given. +if test "${enable_debug+set}" = set; then + enableval="$enable_debug" + mr_enable_debug="$enableval" +else + mr_enable_debug=no +fi + + if test "$mr_enable_debug" = yes; then + cat >> confdefs.h <<\EOF +#define ENABLE_DEBUG 1 +EOF + + fi + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile lib/Makefile po/Makefile libelf.pc config.h lib/sys_elf.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@PACKAGE@%$PACKAGE%g +s%@VERSION@%$VERSION%g +s%@MAINT@%$MAINT%g +s%@MAJOR@%$MAJOR%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@RANLIB@%$RANLIB%g +s%@LN_S@%$LN_S%g +s%@DO_COMPAT@%$DO_COMPAT%g +s%@LIBOBJS@%$LIBOBJS%g +s%@GMOFILES@%$GMOFILES%g +s%@MSGFILES@%$MSGFILES%g +s%@POFILES@%$POFILES%g +s%@MSGFMT@%$MSGFMT%g +s%@GMSGFMT@%$GMSGFMT%g +s%@XGETTEXT@%$XGETTEXT%g +s%@MSGMERGE@%$MSGMERGE%g +s%@GENCAT@%$GENCAT%g +s%@CATOBJEXT@%$CATOBJEXT%g +s%@INSTOBJEXT@%$INSTOBJEXT%g +s%@localedir@%$localedir%g +s%@CATALOGS@%$CATALOGS%g +s%@POSUB@%$POSUB%g +s%@LIBINTL@%$LIBINTL%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@LD@%$LD%g +s%@PICFLAGS@%$PICFLAGS%g +s%@SHLIB_SFX@%$SHLIB_SFX%g +s%@SHLINK_SFX@%$SHLINK_SFX%g +s%@SONAME_SFX@%$SONAME_SFX%g +s%@LINK_SHLIB@%$LINK_SHLIB%g +s%@INSTALL_SHLIB@%$INSTALL_SHLIB%g +s%@DEPSHLIBS@%$DEPSHLIBS%g +s%@DO_SHLIB@%$DO_SHLIB%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +echo timestamp > stamp-h; echo timestamp > lib/stamp-h +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + +# vi: set ts=8 sw=2 : diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/configure.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/configure.in Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,379 @@ +# configure.in - Configure template for libelf. +# Process this file with autoconf to produce a configure script. +# Copyright (C) 1995 - 2006 Michael Riepe +# +# This library 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 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# @(#) $Id: configure.in,v 1.40 2007/09/07 12:07:59 michael Exp $ + +AC_INIT(VERSION) +AC_CONFIG_HEADER(config.h lib/sys_elf.h) + +AC_PREREQ(2.13) + +mr_PACKAGE(libelf) + +dnl NOTE: there must be at least one .po file! +ALL_LINGUAS=`cd $srcdir/po && echo *.po | sed 's/\.po//g'` + +dnl Assuming all arguments have already been processed... +set `echo $VERSION | sed 's/\./ /g'` +MAJOR=${1-1} +MINOR=${2-0} +PATCH=${3-0} +AC_SUBST(MAJOR) + +dnl Checks for programs. +AC_PROG_MAKE_SET +AC_PROG_CC +AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_RANLIB +AC_PROG_LN_S + +dnl Checks for libraries. + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(unistd.h stdint.h fcntl.h) +AC_CHECK_HEADERS(elf.h sys/elf.h link.h sys/link.h) +AC_CACHE_CHECK([if ${CC} can compile elf.h], libelf_cv_elf_h_works, [ + AC_TRY_COMPILE( + [#if HAVE_ELF_H + #include + #elif HAVE_SYS_ELF_H + #include + #endif], + [Elf32_Ehdr dummy], + [libelf_cv_elf_h_works=yes], + [libelf_cv_elf_h_works=no]) +]) +if test "$libelf_cv_elf_h_works" = no; then + ac_cv_header_elf_h=no + ac_cv_header_sys_elf_h=no +fi +if test "$ac_cv_header_elf_h" = yes; then + AC_DEFINE(__LIBELF_HEADER_ELF_H, []) +elif test "$ac_cv_header_sys_elf_h" = yes; then + AC_DEFINE(__LIBELF_HEADER_ELF_H, []) +fi + +AC_CHECK_HEADERS(ar.h libelf.h nlist.h gelf.h) +AC_MSG_CHECKING([whether to install , and ]) +AC_ARG_ENABLE(compat, + [ --enable-compat install , and (default: auto)], + [DO_COMPAT="$enableval"], + [if test "$ac_cv_header_libelf_h$ac_cv_header_nlist_h$ac_cv_header_gelf_h" = yesyesyes + then DO_COMPAT=no + else DO_COMPAT=yes + fi]) +AC_MSG_RESULT($DO_COMPAT) +AC_SUBST(DO_COMPAT) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_OFF_T +AC_TYPE_SIZE_T + +AC_CHECK_SIZEOF(short,2) +AC_CHECK_SIZEOF(int,4) +AC_CHECK_SIZEOF(long,4) +AC_CHECK_SIZEOF(long long,0) +# Windows port +AC_CHECK_SIZEOF(__int64, 0) + +if test "$ac_cv_header_elf_h" = yes \ +|| test "$ac_cv_header_sys_elf_h" = yes; then + + # Slowaris declares Elf32_Dyn in . + # QNX declares Elf32_Dyn in . + AC_CACHE_CHECK([for struct Elf32_Dyn], libelf_cv_struct_elf32_dyn, [ + AC_TRY_COMPILE([#include __LIBELF_HEADER_ELF_H], [Elf32_Dyn x], + [libelf_cv_struct_elf32_dyn=yes], + AC_TRY_COMPILE([#include ], [Elf32_Dyn x], + [libelf_cv_struct_elf32_dyn=link.h], + AC_TRY_COMPILE([#include ], [Elf32_Dyn x], + [libelf_cv_struct_elf32_dyn=sys/link.h], + [libelf_cv_struct_elf32_dyn=no])))]) + if test "$libelf_cv_struct_elf32_dyn" = link.h; then + AC_DEFINE(__LIBELF_NEED_LINK_H) + elif test "$libelf_cv_struct_elf32_dyn" = sys/link.h; then + AC_DEFINE(__LIBELF_NEED_SYS_LINK_H) + elif test "$libelf_cv_struct_elf32_dyn" = no; then + AC_MSG_ERROR([no declaration for Elf32_Dyn]) + fi + + # Linux declares struct nlist in . + AC_CACHE_CHECK([for struct nlist in elf.h], libelf_cv_struct_nlist, [ + AC_TRY_COMPILE([#include __LIBELF_HEADER_ELF_H], [struct nlist nl], + [libelf_cv_struct_nlist=yes], + [libelf_cv_struct_nlist=no])]) + if test "$libelf_cv_struct_nlist" = yes; then + AC_DEFINE(HAVE_STRUCT_NLIST_DECLARATION) + fi + + # Check for 64-bit data types. + AC_CACHE_CHECK([for struct Elf64_Ehdr], libelf_cv_struct_elf64_ehdr, + AC_TRY_COMPILE([#include __LIBELF_HEADER_ELF_H], + [Elf64_Ehdr x], + [libelf_cv_struct_elf64_ehdr=yes], + [libelf_cv_struct_elf64_ehdr=no])) + + # Linux lacks typedefs for scalar ELF64_* types. + AC_CACHE_CHECK([for Elf64_Addr], libelf_cv_type_elf64_addr, + AC_TRY_COMPILE([#include __LIBELF_HEADER_ELF_H], + [Elf64_Addr x], + [libelf_cv_type_elf64_addr=yes], + [libelf_cv_type_elf64_addr=no])) + + # IRIX' struct Elf64_Rel is slightly different. Ugh. + AC_CACHE_CHECK([for struct Elf64_Rel], libelf_cv_struct_elf64_rel, + AC_TRY_COMPILE([#include __LIBELF_HEADER_ELF_H], + [Elf64_Rel x; x.r_info = 1], + [libelf_cv_struct_elf64_rel=yes], + AC_TRY_COMPILE([#include __LIBELF_HEADER_ELF_H], + [Elf64_Rel x; x.r_sym = 1], + [libelf_cv_struct_elf64_rel=irix], + [libelf_cv_struct_elf64_rel=no]))) + + case "$libelf_cv_struct_elf64_ehdr:\ +$libelf_cv_type_elf64_addr:\ +$libelf_cv_struct_elf64_rel" in + yes:yes:yes) + libelf_64bit=yes;; + yes:yes:irix) + AC_DEFINE(__LIBELF64_IRIX) + libelf_64bit=yes;; + yes:no:yes) + AC_DEFINE(__LIBELF64_LINUX) + libelf_64bit=yes;; + *) + libelf_64bit=no;; + esac + + # Check for symbol versioning definitions + AC_CACHE_CHECK([for Elf32_Verdef], libelf_cv_verdef32, + AC_TRY_COMPILE( + [#include __LIBELF_HEADER_ELF_H + #if __LIBELF_NEED_LINK_H + #include /* Solaris wants this */ + #endif], + [struct { + Elf32_Verdef vd; + Elf32_Verdaux vda; + Elf32_Verneed vn; + Elf32_Vernaux vna; + } x], + [libelf_cv_verdef32=yes], + [libelf_cv_verdef32=no])) + + AC_CACHE_CHECK([for Elf64_Verdef], libelf_cv_verdef64, + AC_TRY_COMPILE( + [#include __LIBELF_HEADER_ELF_H + #if __LIBELF_NEED_LINK_H + #include /* Solaris wants this */ + #endif], + [struct { + Elf64_Verdef vd; + Elf64_Verdaux vda; + Elf64_Verneed vn; + Elf64_Vernaux vna; + } x], + [libelf_cv_verdef64=yes], + [libelf_cv_verdef64=no])) + + AC_CACHE_CHECK([for SHT_SUNW_verdef], libelf_cv_sun_verdef, + AC_TRY_COMPILE([#include __LIBELF_HEADER_ELF_H], + [Elf32_Word x = SHT_SUNW_verdef + SHT_SUNW_verneed + SHT_SUNW_versym], + [libelf_cv_sun_verdef=yes], + [libelf_cv_sun_verdef=no])) + + AC_CACHE_CHECK([for SHT_GNU_verdef], libelf_cv_gnu_verdef, + AC_TRY_COMPILE([#include __LIBELF_HEADER_ELF_H], + [Elf32_Word x = SHT_GNU_verdef + SHT_GNU_verneed + SHT_GNU_versym], + [libelf_cv_gnu_verdef=yes], + [libelf_cv_gnu_verdef=no])) +else + # lib/elf_repl.h supports 64-bit + libelf_64bit=yes + + # lib/elf_repl.h supports symbol versioning + libelf_cv_verdef32=yes + libelf_cv_verdef64=yes + libelf_cv_sun_verdef=yes + libelf_cv_gnu_verdef=yes +fi + +AC_CACHE_CHECK([for 64-bit integer], libelf_cv_int64, [ + if test "$ac_cv_sizeof_long" = 8; then + libelf_cv_int64='long' + elif test "$ac_cv_sizeof___int64" = 8; then + libelf_cv_int64='__int64' + elif test "$ac_cv_sizeof_long_long" = 8; then + libelf_cv_int64='long long' + else + libelf_cv_int64=no + fi]) +if test "$libelf_cv_int64" = no; then + libelf_64bit=no +else + AC_DEFINE_UNQUOTED(__libelf_i64_t, [$libelf_cv_int64]) + AC_DEFINE_UNQUOTED(__libelf_u64_t, [unsigned $libelf_cv_int64]) +fi + +AC_CACHE_CHECK([for 32-bit integer], libelf_cv_int32, [ + if test "$ac_cv_sizeof_int" = 4; then + libelf_cv_int32='int' + elif test "$ac_cv_sizeof_long" = 4; then + libelf_cv_int32='long' + else + libelf_cv_int32=no + fi]) +if test "$libelf_cv_int32" = no; then + AC_MSG_ERROR([neither int nor long is 32-bit]) +else + AC_DEFINE_UNQUOTED(__libelf_i32_t, [$libelf_cv_int32]) + AC_DEFINE_UNQUOTED(__libelf_u32_t, [unsigned $libelf_cv_int32]) +fi + +AC_CACHE_CHECK([for 16-bit integer], libelf_cv_int16, [ + if test "$ac_cv_sizeof_short" = 2; then + libelf_cv_int16='short' + elif test "$ac_cv_sizeof_int" = 2; then + libelf_cv_int16='int' + else + libelf_cv_int16=no + fi]) +if test "$libelf_cv_int16" = no; then + AC_MSG_ERROR([neither short nor int is 16-bit]) +else + AC_DEFINE_UNQUOTED(__libelf_i16_t, [$libelf_cv_int16]) + AC_DEFINE_UNQUOTED(__libelf_u16_t, [unsigned $libelf_cv_int16]) +fi + +dnl Checks for library functions. +AC_FUNC_MMAP +AC_CHECK_FUNCS(ftruncate memcmp memcpy memmove) +AC_REPLACE_FUNCS(memset) +if test "$ac_cv_func_memset" = yes; then + AC_DEFINE(HAVE_MEMSET) +fi + +AC_CACHE_CHECK([whether overlapping arrays are copied correctly], + libelf_cv_working_memmove, + [AC_TRY_RUN(changequote(<<, >>)dnl +<<#include "confdefs.h" +#if HAVE_MEMMOVE +extern void *memmove(); +#else +extern void bcopy(); +#define memmove(d,s,n) bcopy((s),(d),(n)) +#endif +extern int strcmp(); +main() { + char buf[] = "0123456789"; + memmove(buf + 1, buf, 9); + if (strcmp(buf, "0012345678")) exit(1); + exit(0); +}>>, changequote([, ])dnl + libelf_cv_working_memmove=yes, + libelf_cv_working_memmove=no, + libelf_cv_working_memmove='maybe not')]) +if test "$libelf_cv_working_memmove" != yes; then + AC_DEFINE(HAVE_BROKEN_MEMMOVE) +fi + +AC_CACHE_CHECK([the coffee machine], mr_cv_coffee_machine, + [mr_cv_coffee_machine='empty - operator may not work as expected']) + +dnl Check for 64-bit support. +AC_MSG_CHECKING([whether 64-bit ELF support is sufficient]) +AC_MSG_RESULT($libelf_64bit) +AC_MSG_CHECKING([whether to include 64-bit support]) +if test "$libelf_64bit" = no; then + libelf_enable_64bit=no +else + AC_ARG_ENABLE(elf64, + [ --enable-elf64 compile in 64-bit support (default: auto)], + [libelf_enable_64bit="$enableval"], + [libelf_enable_64bit=yes]) +fi +AC_MSG_RESULT($libelf_enable_64bit) +if test "$libelf_enable_64bit" = yes; then + AC_DEFINE(__LIBELF64) +fi + +AC_MSG_CHECKING([whether versioning support is sufficient]) +libelf_versioning=no +case "$libelf_enable_64bit:$libelf_cv_verdef32:$libelf_cv_verdef64" in + no:yes:* | yes:yes:yes) + if test "$libelf_cv_sun_verdef" = yes; then + AC_DEFINE(__LIBELF_SUN_SYMBOL_VERSIONS) + libelf_versioning=yes + elif test "$libelf_cv_gnu_verdef" = yes; then + AC_DEFINE(__LIBELF_GNU_SYMBOL_VERSIONS) + libelf_versioning=yes + fi;; +esac +AC_MSG_RESULT($libelf_versioning) +AC_MSG_CHECKING([whether to include versioning support]) +if test "$libelf_versioning" = no; then + libelf_enable_versioning=no +else + AC_ARG_ENABLE(versioning, + [ --enable-versioning compile in versioning support (default: auto)], + [libelf_enable_versioning="$enableval"], + [libelf_enable_versioning=yes]) +fi +AC_MSG_RESULT($libelf_enable_versioning) +if test "$libelf_enable_versioning" = yes; then + AC_DEFINE(__LIBELF_SYMBOL_VERSIONS) +fi + +dnl Check for NLS support. +mr_ENABLE_NLS +dnl this is for gmo2msg... +LIBINTL= +AC_CHECK_LIB(intl, gettext, [LIBINTL=-lintl]) +AC_SUBST(LIBINTL) + +dnl Check for shared library support. +mr_ENABLE_SHARED + +dnl Check for extended ELF format support +AC_ARG_ENABLE(extended-format, + [ --enable-extended-format support extended file formats (default: no)], + [mr_enable_extended_format="$enableval"], + [mr_enable_extended_format=no]) +if test "$mr_enable_extended_format" = yes; then + AC_DEFINE(ENABLE_EXTENDED_FORMAT) +fi + +dnl Check if ELF sanity checks should be enabled +AC_ARG_ENABLE(sanity-checks, + [ --enable-sanity-checks enable sanity checks by default (default: yes)], + [mr_enable_sanity_checks="$enableval"], + [mr_enable_sanity_checks=yes]) +if test "$mr_enable_sanity_checks" = yes; then + AC_DEFINE(ENABLE_SANITY_CHECKS) +fi + +dnl Check for debug support. +mr_ENABLE_DEBUG + +AC_OUTPUT([Makefile lib/Makefile po/Makefile libelf.pc], + [echo timestamp > stamp-h; echo timestamp > lib/stamp-h]) + +# vi: set ts=8 sw=2 : diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/install-sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/install-sh Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,119 @@ +#!/bin/sh + +# +# install - install a program, script, or datafile +# This comes from X11R5; it is not part of GNU. +# +# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" + +instcmd="$mvprog" +chmodcmd="" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +fi + +if [ x"$dst" = x ] +then + echo "install: no destination specified" + exit 1 +fi + + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + +if [ -d $dst ] +then + dst="$dst"/`basename $src` +fi + +# Make a temp file name in the proper directory. + +dstdir=`dirname $dst` +dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + +$doit $instcmd $src $dsttmp + +# and set any options; do chmod last to preserve setuid bits + +if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi +if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi +if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi +if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi + +# Now rename the file to the real destination. + +$doit $rmcmd $dst +$doit $mvcmd $dsttmp $dst + + +exit 0 diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/32.fsize.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/32.fsize.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,155 @@ +/* +32.fsize.c - implementation of the elf{32,64}_fsize(3) functions. +Copyright (C) 1995 - 2001 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: 32.fsize.c,v 1.12 2005/05/21 15:39:19 michael Exp $"; +#endif /* lint */ + +const size_t +_elf_fmsize[2][EV_CURRENT - EV_NONE][ELF_T_NUM][2] = { + /* ELFCLASS32 */ + { + /* version 1 */ + { + { sizeof(unsigned char), sizeof(unsigned char) }, + { sizeof(Elf32_Addr), sizeof(__ext_Elf32_Addr) }, + { sizeof(Elf32_Dyn), sizeof(__ext_Elf32_Dyn) }, + { sizeof(Elf32_Ehdr), sizeof(__ext_Elf32_Ehdr) }, + { sizeof(Elf32_Half), sizeof(__ext_Elf32_Half) }, + { sizeof(Elf32_Off), sizeof(__ext_Elf32_Off) }, + { sizeof(Elf32_Phdr), sizeof(__ext_Elf32_Phdr) }, + { sizeof(Elf32_Rela), sizeof(__ext_Elf32_Rela) }, + { sizeof(Elf32_Rel), sizeof(__ext_Elf32_Rel) }, + { sizeof(Elf32_Shdr), sizeof(__ext_Elf32_Shdr) }, + { sizeof(Elf32_Sword), sizeof(__ext_Elf32_Sword) }, + { sizeof(Elf32_Sym), sizeof(__ext_Elf32_Sym) }, + { sizeof(Elf32_Word), sizeof(__ext_Elf32_Word) }, + { 0, 0 }, /* there is no Elf32_Sxword */ + { 0, 0 }, /* there is no Elf32_Xword */ + /* XXX: check Solaris values */ + { 0, 0 }, /* Elf32_Verdef/Verdaux size varies */ + { 0, 0 }, /* Elf32_Verneed/Vernaux size varies */ + }, + }, +#if __LIBELF64 + /* ELFCLASS64 */ + { + /* version 1 */ + { + { sizeof(unsigned char), sizeof(unsigned char) }, + { sizeof(Elf64_Addr), sizeof(__ext_Elf64_Addr) }, + { sizeof(Elf64_Dyn), sizeof(__ext_Elf64_Dyn) }, + { sizeof(Elf64_Ehdr), sizeof(__ext_Elf64_Ehdr) }, + { sizeof(Elf64_Half), sizeof(__ext_Elf64_Half) }, + { sizeof(Elf64_Off), sizeof(__ext_Elf64_Off) }, + { sizeof(Elf64_Phdr), sizeof(__ext_Elf64_Phdr) }, + { sizeof(Elf64_Rela), sizeof(__ext_Elf64_Rela) }, + { sizeof(Elf64_Rel), sizeof(__ext_Elf64_Rel) }, + { sizeof(Elf64_Shdr), sizeof(__ext_Elf64_Shdr) }, + { sizeof(Elf64_Sword), sizeof(__ext_Elf64_Sword) }, + { sizeof(Elf64_Sym), sizeof(__ext_Elf64_Sym) }, + { sizeof(Elf64_Word), sizeof(__ext_Elf64_Word) }, + { sizeof(Elf64_Sxword), sizeof(__ext_Elf64_Sxword) }, + { sizeof(Elf64_Xword), sizeof(__ext_Elf64_Xword) }, + /* XXX: check Solaris values */ + { 0, 0 }, /* Elf64_Verdef/Verdaux size varies */ + { 0, 0 }, /* Elf64_Verneed/Vernaux size varies */ + }, + }, +#endif /* __LIBELF64 */ +}; + +static size_t +_elf_fsize(unsigned cls, Elf_Type type, unsigned ver) { + size_t n = 0; + + if (!valid_version(ver)) { + seterr(ERROR_UNKNOWN_VERSION); + } + else if (!valid_type(type)) { + seterr(ERROR_UNKNOWN_TYPE); + } + else if (!(n = _fsize(cls, ver, type))) { + seterr(ERROR_UNKNOWN_TYPE); + } + return n; +} + +size_t +elf32_fsize(Elf_Type type, size_t count, unsigned ver) { + return count * _elf_fsize(ELFCLASS32, type, ver); +} + +#if __LIBELF64 + +size_t +elf64_fsize(Elf_Type type, size_t count, unsigned ver) { + return count * _elf_fsize(ELFCLASS64, type, ver); +} + +size_t +gelf_fsize(Elf *elf, Elf_Type type, size_t count, unsigned ver) { + if (elf) { + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (valid_class(elf->e_class)) { + return count * _elf_fsize(elf->e_class, type, ver); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + } + return 0; +} + +/* + * Extension: report memory size + */ +size_t +gelf_msize(Elf *elf, Elf_Type type, size_t count, unsigned ver) { + size_t n; + + if (elf) { + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (!valid_class(elf->e_class)) { + seterr(ERROR_UNKNOWN_CLASS); + } + else if (!valid_version(ver)) { + seterr(ERROR_UNKNOWN_VERSION); + } + else if (!valid_type(type)) { + seterr(ERROR_UNKNOWN_TYPE); + } + else if (!(n = _msize(elf->e_class, ver, type))) { + seterr(ERROR_UNKNOWN_TYPE); + } + else { + return count * n; + } + } + return 0; +} + +#endif /* __LIBELF64 */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/32.getehdr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/32.getehdr.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,56 @@ +/* +32.getehdr.c - implementation of the elf{32,64}_getehdr(3) functions. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: 32.getehdr.c,v 1.8 2005/05/21 15:39:19 michael Exp $"; +#endif /* lint */ + +char* +_elf_getehdr(Elf *elf, unsigned cls) { + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_class != cls) { + seterr(ERROR_CLASSMISMATCH); + } + else if (elf->e_ehdr || _elf_cook(elf)) { + return elf->e_ehdr; + } + return NULL; +} + +Elf32_Ehdr* +elf32_getehdr(Elf *elf) { + return (Elf32_Ehdr*)_elf_getehdr(elf, ELFCLASS32); +} + +#if __LIBELF64 + +Elf64_Ehdr* +elf64_getehdr(Elf *elf) { + return (Elf64_Ehdr*)_elf_getehdr(elf, ELFCLASS64); +} + +#endif /* __LIBELF64 */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/32.getphdr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/32.getphdr.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,56 @@ +/* +32.getphdr.c - implementation of the elf{32,64}_getphdr(3) functions. +Copyright (C) 1995 - 2000 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: 32.getphdr.c,v 1.10 2005/05/21 15:39:19 michael Exp $"; +#endif /* lint */ + +char* +_elf_getphdr(Elf *elf, unsigned cls) { + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_class != cls) { + seterr(ERROR_CLASSMISMATCH); + } + else if (elf->e_ehdr || _elf_cook(elf)) { + return elf->e_phdr; + } + return NULL; +} + +Elf32_Phdr* +elf32_getphdr(Elf *elf) { + return (Elf32_Phdr*)_elf_getphdr(elf, ELFCLASS32); +} + +#if __LIBELF64 + +Elf64_Phdr* +elf64_getphdr(Elf *elf) { + return (Elf64_Phdr*)_elf_getphdr(elf, ELFCLASS64); +} + +#endif /* __LIBELF64 */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/32.getshdr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/32.getshdr.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,58 @@ +/* +32.getshdr.c - implementation of the elf{32,64}_getshdr(3) functions. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: 32.getshdr.c,v 1.9 2005/05/21 15:39:19 michael Exp $"; +#endif /* lint */ + +Elf32_Shdr* +elf32_getshdr(Elf_Scn *scn) { + if (!scn) { + return NULL; + } + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf); + elf_assert(scn->s_elf->e_magic == ELF_MAGIC); + if (scn->s_elf->e_class == ELFCLASS32) { + return &scn->s_shdr32; + } + seterr(ERROR_CLASSMISMATCH); + return NULL; +} + +#if __LIBELF64 + +Elf64_Shdr* +elf64_getshdr(Elf_Scn *scn) { + if (!scn) { + return NULL; + } + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf); + elf_assert(scn->s_elf->e_magic == ELF_MAGIC); + if (scn->s_elf->e_class == ELFCLASS64) { + return &scn->s_shdr64; + } + seterr(ERROR_CLASSMISMATCH); + return NULL; +} + +#endif /* __LIBELF64 */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/32.newehdr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/32.newehdr.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,80 @@ +/* + * 32.newehdr.c - implementation of the elf{32,64}_newehdr(3) functions. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: 32.newehdr.c,v 1.15 2006/07/07 22:15:31 michael Exp $"; +#endif /* lint */ + +static char* +_elf_newehdr(Elf *elf, unsigned cls) { + size_t size; + + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_readable) { + return _elf_getehdr(elf, cls); + } + else if (!elf->e_ehdr) { + size = _msize(cls, _elf_version, ELF_T_EHDR); + elf_assert(size); + if ((elf->e_ehdr = (char*)malloc(size))) { + memset(elf->e_ehdr, 0, size); + elf->e_ehdr_flags |= ELF_F_DIRTY; + elf->e_kind = ELF_K_ELF; + elf->e_class = cls; + return elf->e_ehdr; + } + seterr(ERROR_MEM_EHDR); + } + else if (elf->e_class != cls) { + seterr(ERROR_CLASSMISMATCH); + } + else { + elf_assert(elf->e_kind == ELF_K_ELF); + return elf->e_ehdr; + } + return NULL; +} + +Elf32_Ehdr* +elf32_newehdr(Elf *elf) { + return (Elf32_Ehdr*)_elf_newehdr(elf, ELFCLASS32); +} + +#if __LIBELF64 + +Elf64_Ehdr* +elf64_newehdr(Elf *elf) { + return (Elf64_Ehdr*)_elf_newehdr(elf, ELFCLASS64); +} + +unsigned long +gelf_newehdr(Elf *elf, int cls) { + if (!valid_class(cls) || !_msize(cls, _elf_version, ELF_T_EHDR)) { + seterr(ERROR_UNKNOWN_CLASS); + return 0; + } + return (unsigned long)_elf_newehdr(elf, cls); +} + +#endif /* __LIBELF64 */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/32.newphdr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/32.newphdr.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,118 @@ +/* + * 32.newphdr.c - implementation of the elf{32,64}_newphdr(3) functions. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: 32.newphdr.c,v 1.15 2006/07/07 22:15:41 michael Exp $"; +#endif /* lint */ + +static char* +_elf_newphdr(Elf *elf, size_t count, unsigned cls) { + size_t extcount = 0; + Elf_Scn *scn = NULL; + char *phdr = NULL; + size_t size; + + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (!elf->e_ehdr && !elf->e_readable) { + seterr(ERROR_NOEHDR); + } + else if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_class != cls) { + seterr(ERROR_CLASSMISMATCH); + } + else if (elf->e_ehdr || _elf_cook(elf)) { + size = _msize(cls, _elf_version, ELF_T_PHDR); + elf_assert(size); + if (!(scn = _elf_first_scn(elf))) { + return NULL; + } + if (count) { + if (!(phdr = (char*)malloc(count * size))) { + seterr(ERROR_MEM_PHDR); + return NULL; + } + memset(phdr, 0, count * size); + } + elf_assert(elf->e_ehdr); + elf->e_phnum = count; + if (count >= PN_XNUM) { + /* + * get NULL section (create it if necessary) + */ + extcount = count; + count = PN_XNUM; + } + if (cls == ELFCLASS32) { + ((Elf32_Ehdr*)elf->e_ehdr)->e_phnum = count; + scn->s_shdr32.sh_info = extcount; + } +#if __LIBELF64 + else if (cls == ELFCLASS64) { + ((Elf64_Ehdr*)elf->e_ehdr)->e_phnum = count; + scn->s_shdr64.sh_info = extcount; + } +#endif /* __LIBELF64 */ + else { + seterr(ERROR_UNIMPLEMENTED); + if (phdr) { + free(phdr); + } + return NULL; + } + if (elf->e_phdr) { + free(elf->e_phdr); + } + elf->e_phdr = phdr; + elf->e_phdr_flags |= ELF_F_DIRTY; + elf->e_ehdr_flags |= ELF_F_DIRTY; + scn->s_scn_flags |= ELF_F_DIRTY; + return phdr; + } + return NULL; +} + +Elf32_Phdr* +elf32_newphdr(Elf *elf, size_t count) { + return (Elf32_Phdr*)_elf_newphdr(elf, count, ELFCLASS32); +} + +#if __LIBELF64 + +Elf64_Phdr* +elf64_newphdr(Elf *elf, size_t count) { + return (Elf64_Phdr*)_elf_newphdr(elf, count, ELFCLASS64); +} + +unsigned long +gelf_newphdr(Elf *elf, size_t phnum) { + if (!valid_class(elf->e_class)) { + seterr(ERROR_UNKNOWN_CLASS); + return 0; + } + return (unsigned long)_elf_newphdr(elf, phnum, elf->e_class); +} + +#endif /* __LIBELF64 */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/32.xlatetof.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/32.xlatetof.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,438 @@ +/* + * 32.xlatetof.c - implementation of the elf32_xlateto[fm](3) functions. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: 32.xlatetof.c,v 1.26 2006/07/27 22:33:40 michael Exp $"; +#endif /* lint */ + +/* + * Ugly, ugly + */ +#ifdef _WIN32 +# define Cat2(a,b)a##b +# define Cat3(a,b,c)a##b##c +# define Ex1(m1,m2,a,b)m1##m2(a##b) +# define Ex2(m1,m2,a,b,c)m1##m2(a,b##c) +#else /* _WIN32 */ +# define x +# if defined/**/x +# define Cat2(a,b)a##b +# define Cat3(a,b,c)a##b##c +# define Ex1(m1,m2,a,b)m1##m2(a##b) +# define Ex2(m1,m2,a,b,c)m1##m2(a,b##c) +# else +# define Cat2(a,b)a/**/b +# define Cat3(a,b,c)a/**/b/**/c +# define Ex1(m1,m2,a,b)m1/**/m2(a/**/b) +# define Ex2(m1,m2,a,b,c)m1/**/m2(a,b/**/c) +# endif +# undef x +#endif /* _WIN32 */ + +/* + * auxiliary macros for execution order reversal + */ +#define seq_forw(a,b) a b +#define seq_back(a,b) b a + +/* + * function instantiator + */ +#define copy_type_e_io(name,e,io,tfrom,tto,copy) \ + static size_t \ + Cat3(name,_,io)(unsigned char *dst, const unsigned char *src, size_t n) { \ + n /= sizeof(tfrom); \ + if (n && dst) { \ + const tfrom *from = (const tfrom*)src; \ + tto *to = (tto*)dst; \ + size_t i; \ + \ + if (sizeof(tfrom) < sizeof(tto)) { \ + from += n; \ + to += n; \ + for (i = 0; i < n; i++) { \ + --from; \ + --to; \ + copy(e,io,seq_back) \ + } \ + } \ + else { \ + for (i = 0; i < n; i++) { \ + copy(e,io,seq_forw) \ + from++; \ + to++; \ + } \ + } \ + } \ + return n * sizeof(tto); \ + } + +#define copy_type_e(name,e,type,copy) \ + copy_type_e_io(name,e,tom,Cat2(__ext_,type),type,copy) \ + copy_type_e_io(name,e,tof,type,Cat2(__ext_,type),copy) + +/* + * master function instantiator + */ +#define copy_type(name,version,type,copy) \ + copy_type_e(Cat3(name,L,version),L,type,copy) \ + copy_type_e(Cat3(name,M,version),M,type,copy) + +/* + * scalar copying + */ +#define copy_scalar_tom(type) *to = Cat2(__load_,type)(*from); +#define copy_scalar_tof(type) Cat2(__store_,type)(*to, *from); + +/* + * structure member copying + */ +#define copy_tom(mb,type) to->mb = Cat2(__load_,type)(from->mb); +#define copy_tof(mb,type) Cat2(__store_,type)(to->mb, from->mb); + +/* + * structure member copying (direction independent) + */ +#define copy_byte(e,io,mb) to->mb = from->mb; +#define copy_addr(e,io,mb) Ex2(copy_,io,mb,u32,e) +#define copy_half(e,io,mb) Ex2(copy_,io,mb,u16,e) +#define copy_off(e,io,mb) Ex2(copy_,io,mb,u32,e) +#define copy_sword(e,io,mb) Ex2(copy_,io,mb,i32,e) +#define copy_word(e,io,mb) Ex2(copy_,io,mb,u32,e) +#define copy_arr(e,io,mb) \ + array_copy(to->mb, sizeof(to->mb), from->mb, sizeof(from->mb)); + +/* + * scalar copying (direction independent) + * these macros are used as `copy' arguments to copy_type() + */ +#define copy_addr_11(e,io,seq) Ex1(copy_scalar_,io,u32,e) +#define copy_half_11(e,io,seq) Ex1(copy_scalar_,io,u16,e) +#define copy_off_11(e,io,seq) Ex1(copy_scalar_,io,u32,e) +#define copy_sword_11(e,io,seq) Ex1(copy_scalar_,io,i32,e) +#define copy_word_11(e,io,seq) Ex1(copy_scalar_,io,u32,e) + +/* + * structure copying (direction independent) + * these macros are used as `copy' arguments to copy_type() + */ +#define copy_dyn_11(e,io,seq) \ + seq(copy_sword(e,io,d_tag), \ + seq(copy_addr(e,io,d_un.d_ptr), \ + nullcopy)) +#define copy_ehdr_11(e,io,seq) \ + seq(copy_arr(e,io,e_ident), \ + seq(copy_half(e,io,e_type), \ + seq(copy_half(e,io,e_machine), \ + seq(copy_word(e,io,e_version), \ + seq(copy_addr(e,io,e_entry), \ + seq(copy_off(e,io,e_phoff), \ + seq(copy_off(e,io,e_shoff), \ + seq(copy_word(e,io,e_flags), \ + seq(copy_half(e,io,e_ehsize), \ + seq(copy_half(e,io,e_phentsize), \ + seq(copy_half(e,io,e_phnum), \ + seq(copy_half(e,io,e_shentsize), \ + seq(copy_half(e,io,e_shnum), \ + seq(copy_half(e,io,e_shstrndx), \ + nullcopy)))))))))))))) +#define copy_phdr_11(e,io,seq) \ + seq(copy_word(e,io,p_type), \ + seq(copy_off(e,io,p_offset), \ + seq(copy_addr(e,io,p_vaddr), \ + seq(copy_addr(e,io,p_paddr), \ + seq(copy_word(e,io,p_filesz), \ + seq(copy_word(e,io,p_memsz), \ + seq(copy_word(e,io,p_flags), \ + seq(copy_word(e,io,p_align), \ + nullcopy)))))))) +#define copy_rela_11(e,io,seq) \ + seq(copy_addr(e,io,r_offset), \ + seq(copy_word(e,io,r_info), \ + seq(copy_sword(e,io,r_addend), \ + nullcopy))) +#define copy_rel_11(e,io,seq) \ + seq(copy_addr(e,io,r_offset), \ + seq(copy_word(e,io,r_info), \ + nullcopy)) +#define copy_shdr_11(e,io,seq) \ + seq(copy_word(e,io,sh_name), \ + seq(copy_word(e,io,sh_type), \ + seq(copy_word(e,io,sh_flags), \ + seq(copy_addr(e,io,sh_addr), \ + seq(copy_off(e,io,sh_offset), \ + seq(copy_word(e,io,sh_size), \ + seq(copy_word(e,io,sh_link), \ + seq(copy_word(e,io,sh_info), \ + seq(copy_word(e,io,sh_addralign), \ + seq(copy_word(e,io,sh_entsize), \ + nullcopy)))))))))) +#define copy_sym_11(e,io,seq) \ + seq(copy_word(e,io,st_name), \ + seq(copy_addr(e,io,st_value), \ + seq(copy_word(e,io,st_size), \ + seq(copy_byte(e,io,st_info), \ + seq(copy_byte(e,io,st_other), \ + seq(copy_half(e,io,st_shndx), \ + nullcopy)))))) + +#define nullcopy /**/ + +static size_t +byte_copy(unsigned char *dst, const unsigned char *src, size_t n) { + if (n && dst && dst != src) { +#if HAVE_BROKEN_MEMMOVE + size_t i; + + if (dst >= src + n || dst + n <= src) { + memcpy(dst, src, n); + } + else if (dst < src) { + for (i = 0; i < n; i++) { + dst[i] = src[i]; + } + } + else { + for (i = n; --i; ) { + dst[i] = src[i]; + } + } +#else /* HAVE_BROKEN_MEMMOVE */ + memmove(dst, src, n); +#endif /* HAVE_BROKEN_MEMMOVE */ + } + return n; +} + +static void +array_copy(unsigned char *dst, size_t dlen, const unsigned char *src, size_t slen) { + byte_copy(dst, src, dlen < slen ? dlen : slen); + if (dlen > slen) { + memset(dst + slen, 0, dlen - slen); + } +} + +/* + * instantiate copy functions + */ +copy_type(addr_32,_,Elf32_Addr,copy_addr_11) +copy_type(half_32,_,Elf32_Half,copy_half_11) +copy_type(off_32,_,Elf32_Off,copy_off_11) +copy_type(sword_32,_,Elf32_Sword,copy_sword_11) +copy_type(word_32,_,Elf32_Word,copy_word_11) +copy_type(dyn_32,11,Elf32_Dyn,copy_dyn_11) +copy_type(ehdr_32,11,Elf32_Ehdr,copy_ehdr_11) +copy_type(phdr_32,11,Elf32_Phdr,copy_phdr_11) +copy_type(rela_32,11,Elf32_Rela,copy_rela_11) +copy_type(rel_32,11,Elf32_Rel,copy_rel_11) +copy_type(shdr_32,11,Elf32_Shdr,copy_shdr_11) +copy_type(sym_32,11,Elf32_Sym,copy_sym_11) + +typedef size_t (*xlator)(unsigned char*, const unsigned char*, size_t); +typedef xlator xltab[ELF_T_NUM][2]; + +/* + * translation table (32-bit, version 1 -> version 1) + */ +#if PIC +static xltab +#else /* PIC */ +static const xltab +#endif /* PIC */ +xlate32_11[/*encoding*/] = { + { + { byte_copy, byte_copy }, + { addr_32L__tom, addr_32L__tof }, + { dyn_32L11_tom, dyn_32L11_tof }, + { ehdr_32L11_tom, ehdr_32L11_tof }, + { half_32L__tom, half_32L__tof }, + { off_32L__tom, off_32L__tof }, + { phdr_32L11_tom, phdr_32L11_tof }, + { rela_32L11_tom, rela_32L11_tof }, + { rel_32L11_tom, rel_32L11_tof }, + { shdr_32L11_tom, shdr_32L11_tof }, + { sword_32L__tom, sword_32L__tof }, + { sym_32L11_tom, sym_32L11_tof }, + { word_32L__tom, word_32L__tof }, + { 0, 0 }, /* there is no Sxword */ + { 0, 0 }, /* there is no Xword */ +#if __LIBELF_SYMBOL_VERSIONS + { _elf_verdef_32L11_tom, _elf_verdef_32L11_tof }, + { _elf_verneed_32L11_tom, _elf_verneed_32L11_tof }, +#else /* __LIBELF_SYMBOL_VERSIONS */ + { 0, 0 }, + { 0, 0 }, +#endif /* __LIBELF_SYMBOL_VERSIONS */ + }, + { + { byte_copy, byte_copy }, + { addr_32M__tom, addr_32M__tof }, + { dyn_32M11_tom, dyn_32M11_tof }, + { ehdr_32M11_tom, ehdr_32M11_tof }, + { half_32M__tom, half_32M__tof }, + { off_32M__tom, off_32M__tof }, + { phdr_32M11_tom, phdr_32M11_tof }, + { rela_32M11_tom, rela_32M11_tof }, + { rel_32M11_tom, rel_32M11_tof }, + { shdr_32M11_tom, shdr_32M11_tof }, + { sword_32M__tom, sword_32M__tof }, + { sym_32M11_tom, sym_32M11_tof }, + { word_32M__tom, word_32M__tof }, + { 0, 0 }, /* there is no Sxword */ + { 0, 0 }, /* there is no Xword */ +#if __LIBELF_SYMBOL_VERSIONS + { _elf_verdef_32M11_tom, _elf_verdef_32M11_tof }, + { _elf_verneed_32M11_tom, _elf_verneed_32M11_tof }, +#else /* __LIBELF_SYMBOL_VERSIONS */ + { 0, 0 }, + { 0, 0 }, +#endif /* __LIBELF_SYMBOL_VERSIONS */ + }, +}; + +/* + * main translation table (32-bit) + */ +#if PIC +static xltab* +#else /* PIC */ +static const xltab *const +#endif /* PIC */ +xlate32[EV_CURRENT - EV_NONE][EV_CURRENT - EV_NONE] = { + { xlate32_11, }, +}; + +#define translator(sv,dv,enc,type,d) \ + (xlate32[(sv) - EV_NONE - 1] \ + [(dv) - EV_NONE - 1] \ + [(enc) - ELFDATA2LSB] \ + [(type) - ELF_T_BYTE] \ + [d]) + +/* + * destination buffer size + */ +size_t +_elf32_xltsize(const Elf_Data *src, unsigned dv, unsigned encode, int tof) { + Elf_Type type = src->d_type; + unsigned sv = src->d_version; + xlator op; + + if (!valid_version(sv) || !valid_version(dv)) { + seterr(ERROR_UNKNOWN_VERSION); + return (size_t)-1; + } + if (tof) { + /* + * Encoding doesn't really matter (the translator only looks at + * the source, which resides in memory), but we need a proper + * encoding to select a translator... + */ + encode = ELFDATA2LSB; + } + else if (!valid_encoding(encode)) { + seterr(ERROR_UNKNOWN_ENCODING); + return (size_t)-1; + } + if (!valid_type(type)) { + seterr(ERROR_UNKNOWN_TYPE); + return (size_t)-1; + } + if (!(op = translator(sv, dv, encode, type, tof))) { + seterr(ERROR_UNKNOWN_TYPE); + return (size_t)-1; + } + return (*op)(NULL, src->d_buf, src->d_size); +} + +/* + * direction-independent translation + */ +static Elf_Data* +elf32_xlate(Elf_Data *dst, const Elf_Data *src, unsigned encode, int tof) { + Elf_Type type; + int dv; + int sv; + size_t dsize; + size_t tmp; + xlator op; + + if (!src || !dst) { + return NULL; + } + if (!src->d_buf || !dst->d_buf) { + seterr(ERROR_NULLBUF); + return NULL; + } + if (!valid_encoding(encode)) { + seterr(ERROR_UNKNOWN_ENCODING); + return NULL; + } + sv = src->d_version; + dv = dst->d_version; + if (!valid_version(sv) || !valid_version(dv)) { + seterr(ERROR_UNKNOWN_VERSION); + return NULL; + } + type = src->d_type; + if (!valid_type(type)) { + seterr(ERROR_UNKNOWN_TYPE); + return NULL; + } + op = translator(sv, dv, encode, type, tof); + if (!op) { + seterr(ERROR_UNKNOWN_TYPE); + return NULL; + } + dsize = (*op)(NULL, src->d_buf, src->d_size); + if (dsize == (size_t)-1) { + return NULL; + } + if (dst->d_size < dsize) { + seterr(ERROR_DST2SMALL); + return NULL; + } + if (dsize) { + tmp = (*op)(dst->d_buf, src->d_buf, src->d_size); + if (tmp == (size_t)-1) { + return NULL; + } + elf_assert(tmp == dsize); + } + dst->d_size = dsize; + dst->d_type = type; + return dst; +} + +/* + * finally, the "official" translation functions + */ +Elf_Data* +elf32_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned encode) { + return elf32_xlate(dst, src, encode, 0); +} + +Elf_Data* +elf32_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned encode) { + return elf32_xlate(dst, src, encode, 1); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/64.xlatetof.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/64.xlatetof.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,512 @@ +/* + * 64.xlatetof.c - implementation of the elf64_xlateto[fm](3) functions. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +#if __LIBELF64 + +#ifndef lint +static const char rcsid[] = "@(#) $Id: 64.xlatetof.c,v 1.26 2006/07/27 22:33:40 michael Exp $"; +#endif /* lint */ + +/* + * Ugly, ugly + */ +#ifdef _WIN32 +# define Cat2(a,b)a##b +# define Cat3(a,b,c)a##b##c +# define Ex1(m1,m2,a,b)m1##m2(a##b) +# define Ex2(m1,m2,a,b,c)m1##m2(a,b##c) +#else /* _WIN32 */ +# define x +# if defined/**/x +# define Cat2(a,b)a##b +# define Cat3(a,b,c)a##b##c +# define Ex1(m1,m2,a,b)m1##m2(a##b) +# define Ex2(m1,m2,a,b,c)m1##m2(a,b##c) +# else +# define Cat2(a,b)a/**/b +# define Cat3(a,b,c)a/**/b/**/c +# define Ex1(m1,m2,a,b)m1/**/m2(a/**/b) +# define Ex2(m1,m2,a,b,c)m1/**/m2(a,b/**/c) +# endif +# undef x +#endif /* _WIN32 */ + +/* + * auxiliary macros for execution order reversal + */ +#define seq_forw(a,b) a b +#define seq_back(a,b) b a + +/* + * function instantiator + */ +#define copy_type_e_io(name,e,io,tfrom,tto,copy) \ + static size_t \ + Cat3(name,_,io)(unsigned char *dst, const unsigned char *src, size_t n) { \ + n /= sizeof(tfrom); \ + if (n && dst) { \ + const tfrom *from = (const tfrom*)src; \ + tto *to = (tto*)dst; \ + size_t i; \ + \ + if (sizeof(tfrom) < sizeof(tto)) { \ + from += n; \ + to += n; \ + for (i = 0; i < n; i++) { \ + --from; \ + --to; \ + copy(e,io,seq_back) \ + } \ + } \ + else { \ + for (i = 0; i < n; i++) { \ + copy(e,io,seq_forw) \ + from++; \ + to++; \ + } \ + } \ + } \ + return n * sizeof(tto); \ + } + +#define copy_type_e(name,e,type,copy) \ + copy_type_e_io(name,e,tom,Cat2(__ext_,type),type,copy) \ + copy_type_e_io(name,e,tof,type,Cat2(__ext_,type),copy) + +/* + * master function instantiator + */ +#define copy_type(name,version,type,copy) \ + copy_type_e(Cat3(name,L,version),L,type,copy) \ + copy_type_e(Cat3(name,M,version),M,type,copy) + +/* + * scalar copying + */ +#define copy_scalar_tom(type) *to = Cat2(__load_,type)(*from); +#define copy_scalar_tof(type) Cat2(__store_,type)(*to, *from); + +/* + * structure member copying + */ +#define copy_tom(mb,type) to->mb = Cat2(__load_,type)(from->mb); +#define copy_tof(mb,type) Cat2(__store_,type)(to->mb, from->mb); + +/* + * structure member copying (direction independent) + */ +#define copy_byte(e,io,mb) to->mb = from->mb; +#define copy_addr(e,io,mb) Ex2(copy_,io,mb,u64,e) +#define copy_half(e,io,mb) Ex2(copy_,io,mb,u16,e) +#define copy_off(e,io,mb) Ex2(copy_,io,mb,u64,e) +#define copy_sword(e,io,mb) Ex2(copy_,io,mb,i32,e) +#define copy_word(e,io,mb) Ex2(copy_,io,mb,u32,e) +#define copy_sxword(e,io,mb) Ex2(copy_,io,mb,i64,e) +#define copy_xword(e,io,mb) Ex2(copy_,io,mb,u64,e) +#define copy_arr(e,io,mb) \ + array_copy(to->mb, sizeof(to->mb), from->mb, sizeof(from->mb)); + +/* + * scalar copying (direction independent) + * these macros are used as `copy' arguments to copy_type() + */ +#define copy_addr_11(e,io,seq) Ex1(copy_scalar_,io,u64,e) +#define copy_half_11(e,io,seq) Ex1(copy_scalar_,io,u16,e) +#define copy_off_11(e,io,seq) Ex1(copy_scalar_,io,u64,e) +#define copy_sword_11(e,io,seq) Ex1(copy_scalar_,io,i32,e) +#define copy_word_11(e,io,seq) Ex1(copy_scalar_,io,u32,e) +#define copy_sxword_11(e,io,seq)Ex1(copy_scalar_,io,i64,e) +#define copy_xword_11(e,io,seq) Ex1(copy_scalar_,io,u64,e) + +/* + * structure copying (direction independent) + * these macros are used as `copy' arguments to copy_type() + */ +#define copy_dyn_11(e,io,seq) \ + seq(copy_xword(e,io,d_tag), \ + seq(copy_addr(e,io,d_un.d_ptr), \ + nullcopy)) +#define copy_ehdr_11(e,io,seq) \ + seq(copy_arr(e,io,e_ident), \ + seq(copy_half(e,io,e_type), \ + seq(copy_half(e,io,e_machine), \ + seq(copy_word(e,io,e_version), \ + seq(copy_addr(e,io,e_entry), \ + seq(copy_off(e,io,e_phoff), \ + seq(copy_off(e,io,e_shoff), \ + seq(copy_word(e,io,e_flags), \ + seq(copy_half(e,io,e_ehsize), \ + seq(copy_half(e,io,e_phentsize), \ + seq(copy_half(e,io,e_phnum), \ + seq(copy_half(e,io,e_shentsize), \ + seq(copy_half(e,io,e_shnum), \ + seq(copy_half(e,io,e_shstrndx), \ + nullcopy)))))))))))))) +#define copy_phdr_11(e,io,seq) \ + seq(copy_word(e,io,p_type), \ + seq(copy_word(e,io,p_flags), \ + seq(copy_off(e,io,p_offset), \ + seq(copy_addr(e,io,p_vaddr), \ + seq(copy_addr(e,io,p_paddr), \ + seq(copy_xword(e,io,p_filesz), \ + seq(copy_xword(e,io,p_memsz), \ + seq(copy_xword(e,io,p_align), \ + nullcopy)))))))) +#if __LIBELF64_IRIX +#define copy_rela_11(e,io,seq) \ + seq(copy_addr(e,io,r_offset), \ + seq(copy_word(e,io,r_sym), \ + seq(copy_byte(e,io,r_ssym), \ + seq(copy_byte(e,io,r_type3), \ + seq(copy_byte(e,io,r_type2), \ + seq(copy_byte(e,io,r_type), \ + seq(copy_sxword(e,io,r_addend), \ + nullcopy))))))) +#define copy_rel_11(e,io,seq) \ + seq(copy_addr(e,io,r_offset), \ + seq(copy_word(e,io,r_sym), \ + seq(copy_byte(e,io,r_ssym), \ + seq(copy_byte(e,io,r_type3), \ + seq(copy_byte(e,io,r_type2), \ + seq(copy_byte(e,io,r_type), \ + nullcopy)))))) +#else /* __LIBELF64_IRIX */ +#define copy_rela_11(e,io,seq) \ + seq(copy_addr(e,io,r_offset), \ + seq(copy_xword(e,io,r_info), \ + seq(copy_sxword(e,io,r_addend), \ + nullcopy))) +#define copy_rel_11(e,io,seq) \ + seq(copy_addr(e,io,r_offset), \ + seq(copy_xword(e,io,r_info), \ + nullcopy)) +#endif /* __LIBELF64_IRIX */ +#define copy_shdr_11(e,io,seq) \ + seq(copy_word(e,io,sh_name), \ + seq(copy_word(e,io,sh_type), \ + seq(copy_xword(e,io,sh_flags), \ + seq(copy_addr(e,io,sh_addr), \ + seq(copy_off(e,io,sh_offset), \ + seq(copy_xword(e,io,sh_size), \ + seq(copy_word(e,io,sh_link), \ + seq(copy_word(e,io,sh_info), \ + seq(copy_xword(e,io,sh_addralign), \ + seq(copy_xword(e,io,sh_entsize), \ + nullcopy)))))))))) +#define copy_sym_11(e,io,seq) \ + seq(copy_word(e,io,st_name), \ + seq(copy_byte(e,io,st_info), \ + seq(copy_byte(e,io,st_other), \ + seq(copy_half(e,io,st_shndx), \ + seq(copy_addr(e,io,st_value), \ + seq(copy_xword(e,io,st_size), \ + nullcopy)))))) + +#define nullcopy /**/ + +static size_t +byte_copy(unsigned char *dst, const unsigned char *src, size_t n) { + if (n && dst && dst != src) { +#if HAVE_BROKEN_MEMMOVE + size_t i; + + if (dst >= src + n || dst + n <= src) { + memcpy(dst, src, n); + } + else if (dst < src) { + for (i = 0; i < n; i++) { + dst[i] = src[i]; + } + } + else { + for (i = n; --i; ) { + dst[i] = src[i]; + } + } +#else /* HAVE_BROKEN_MEMMOVE */ + memmove(dst, src, n); +#endif /* HAVE_BROKEN_MEMMOVE */ + } + return n; +} + +static void +array_copy(unsigned char *dst, size_t dlen, const unsigned char *src, size_t slen) { + byte_copy(dst, src, dlen < slen ? dlen : slen); + if (dlen > slen) { + memset(dst + slen, 0, dlen - slen); + } +} + +/* + * instantiate copy functions + */ +copy_type(addr_64,_,Elf64_Addr,copy_addr_11) +copy_type(half_64,_,Elf64_Half,copy_half_11) +copy_type(off_64,_,Elf64_Off,copy_off_11) +copy_type(sword_64,_,Elf64_Sword,copy_sword_11) +copy_type(word_64,_,Elf64_Word,copy_word_11) +copy_type(sxword_64,_,Elf64_Sxword,copy_sxword_11) +copy_type(xword_64,_,Elf64_Xword,copy_xword_11) +copy_type(dyn_64,11,Elf64_Dyn,copy_dyn_11) +copy_type(ehdr_64,11,Elf64_Ehdr,copy_ehdr_11) +copy_type(phdr_64,11,Elf64_Phdr,copy_phdr_11) +copy_type(rela_64,11,Elf64_Rela,copy_rela_11) +copy_type(rel_64,11,Elf64_Rel,copy_rel_11) +copy_type(shdr_64,11,Elf64_Shdr,copy_shdr_11) +copy_type(sym_64,11,Elf64_Sym,copy_sym_11) + +typedef size_t (*xlator)(unsigned char*, const unsigned char*, size_t); +typedef xlator xltab[ELF_T_NUM][2]; + +/* + * translation table (64-bit, version 1 -> version 1) + */ +#if PIC +static xltab +#else /* PIC */ +static const xltab +#endif /* PIC */ +xlate64_11[/*encoding*/] = { + { + { byte_copy, byte_copy }, + { addr_64L__tom, addr_64L__tof }, + { dyn_64L11_tom, dyn_64L11_tof }, + { ehdr_64L11_tom, ehdr_64L11_tof }, + { half_64L__tom, half_64L__tof }, + { off_64L__tom, off_64L__tof }, + { phdr_64L11_tom, phdr_64L11_tof }, + { rela_64L11_tom, rela_64L11_tof }, + { rel_64L11_tom, rel_64L11_tof }, + { shdr_64L11_tom, shdr_64L11_tof }, + { sword_64L__tom, sword_64L__tof }, + { sym_64L11_tom, sym_64L11_tof }, + { word_64L__tom, word_64L__tof }, + { sxword_64L__tom, sxword_64L__tof }, + { xword_64L__tom, xword_64L__tof }, +#if __LIBELF_SYMBOL_VERSIONS + { _elf_verdef_64L11_tom, _elf_verdef_64L11_tof }, + { _elf_verneed_64L11_tom, _elf_verneed_64L11_tof }, +#else /* __LIBELF_SYMBOL_VERSIONS */ + { 0, 0 }, + { 0, 0 }, +#endif /* __LIBELF_SYMBOL_VERSIONS */ + }, + { + { byte_copy, byte_copy }, + { addr_64M__tom, addr_64M__tof }, + { dyn_64M11_tom, dyn_64M11_tof }, + { ehdr_64M11_tom, ehdr_64M11_tof }, + { half_64M__tom, half_64M__tof }, + { off_64M__tom, off_64M__tof }, + { phdr_64M11_tom, phdr_64M11_tof }, + { rela_64M11_tom, rela_64M11_tof }, + { rel_64M11_tom, rel_64M11_tof }, + { shdr_64M11_tom, shdr_64M11_tof }, + { sword_64M__tom, sword_64M__tof }, + { sym_64M11_tom, sym_64M11_tof }, + { word_64M__tom, word_64M__tof }, + { sxword_64M__tom, sxword_64M__tof }, + { xword_64M__tom, xword_64M__tof }, +#if __LIBELF_SYMBOL_VERSIONS + { _elf_verdef_64M11_tom, _elf_verdef_64M11_tof }, + { _elf_verneed_64M11_tom, _elf_verneed_64M11_tof }, +#else /* __LIBELF_SYMBOL_VERSIONS */ + { 0, 0 }, + { 0, 0 }, +#endif /* __LIBELF_SYMBOL_VERSIONS */ + }, +}; + +/* + * main translation table (64-bit) + */ +#if PIC +static xltab* +#else /* PIC */ +static const xltab *const +#endif /* PIC */ +xlate64[EV_CURRENT - EV_NONE][EV_CURRENT - EV_NONE] = { + { xlate64_11, }, +}; + +#define translator(sv,dv,enc,type,d) \ + (xlate64[(sv) - EV_NONE - 1] \ + [(dv) - EV_NONE - 1] \ + [(enc) - ELFDATA2LSB] \ + [(type) - ELF_T_BYTE] \ + [d]) + +/* + * destination buffer size + */ +size_t +_elf64_xltsize(const Elf_Data *src, unsigned dv, unsigned encode, int tof) { + Elf_Type type = src->d_type; + unsigned sv = src->d_version; + xlator op; + + if (!valid_version(sv) || !valid_version(dv)) { + seterr(ERROR_UNKNOWN_VERSION); + return (size_t)-1; + } + if (tof) { + /* + * Encoding doesn't really matter (the translator only looks at + * the source, which resides in memory), but we need a proper + * encoding to select a translator... + */ + encode = ELFDATA2LSB; + } + else if (!valid_encoding(encode)) { + seterr(ERROR_UNKNOWN_ENCODING); + return (size_t)-1; + } + if (!valid_type(type)) { + seterr(ERROR_UNKNOWN_TYPE); + return (size_t)-1; + } + if (!(op = translator(sv, dv, encode, type, tof))) { + seterr(ERROR_UNKNOWN_TYPE); + return (size_t)-1; + } + return (*op)(NULL, src->d_buf, src->d_size); +} + +/* + * direction-independent translation + */ +static Elf_Data* +elf64_xlate(Elf_Data *dst, const Elf_Data *src, unsigned encode, int tof) { + Elf_Type type; + int dv; + int sv; + size_t dsize; + size_t tmp; + xlator op; + + if (!src || !dst) { + return NULL; + } + if (!src->d_buf || !dst->d_buf) { + seterr(ERROR_NULLBUF); + return NULL; + } + if (!valid_encoding(encode)) { + seterr(ERROR_UNKNOWN_ENCODING); + return NULL; + } + sv = src->d_version; + dv = dst->d_version; + if (!valid_version(sv) || !valid_version(dv)) { + seterr(ERROR_UNKNOWN_VERSION); + return NULL; + } + type = src->d_type; + if (!valid_type(type)) { + seterr(ERROR_UNKNOWN_TYPE); + return NULL; + } + op = translator(sv, dv, encode, type, tof); + if (!op) { + seterr(ERROR_UNKNOWN_TYPE); + return NULL; + } + dsize = (*op)(NULL, src->d_buf, src->d_size); + if (dsize == (size_t)-1) { + return NULL; + } + if (dst->d_size < dsize) { + seterr(ERROR_DST2SMALL); + return NULL; + } + if (dsize) { + tmp = (*op)(dst->d_buf, src->d_buf, src->d_size); + if (tmp == (size_t)-1) { + return NULL; + } + elf_assert(tmp == dsize); + } + dst->d_size = dsize; + dst->d_type = type; + return dst; +} + +/* + * finally, the "official" translation functions + */ +Elf_Data* +elf64_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned encode) { + return elf64_xlate(dst, src, encode, 0); +} + +Elf_Data* +elf64_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned encode) { + return elf64_xlate(dst, src, encode, 1); +} + +Elf_Data* +gelf_xlatetom(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) { + if (elf) { + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_class == ELFCLASS32) { + return elf32_xlatetom(dst, src, encode); + } + else if (elf->e_class == ELFCLASS64) { + return elf64_xlatetom(dst, src, encode); + } + else if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + } + return NULL; +} + +Elf_Data* +gelf_xlatetof(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) { + if (elf) { + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_class == ELFCLASS32) { + return elf32_xlatetof(dst, src, encode); + } + else if (elf->e_class == ELFCLASS64) { + return elf64_xlatetof(dst, src, encode); + } + else if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + } + return NULL; +} + +#endif /* __LIBELF64__ */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/Makefile.in Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,278 @@ +# lib/Makefile for libelf. +# Copyright (C) 1995 - 2006 Michael Riepe +# +# This library 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 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# @(#) $Id: Makefile.in,v 1.38 2007/06/29 21:34:25 michael Exp $ + +instroot = + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@ +includedir = @includedir@ +installdirs = $(libdir) $(includedir) $(includedir)/libelf + +CC = @CC@ +LD = @LD@ +AR = ar +MV = mv -f +RM = rm -f +LN_S = @LN_S@ +RANLIB = @RANLIB@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ + +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +DEFS = -DHAVE_CONFIG_H +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +DEPSHLIBS = @DEPSHLIBS@ + +DO_SHLIB = @DO_SHLIB@ +PICFLAGS = @PICFLAGS@ +SHLIB_SFX = @SHLIB_SFX@ +SHLINK_SFX = @SHLINK_SFX@ +SONAME_SFX = @SONAME_SFX@ +LINK_SHLIB = @LINK_SHLIB@ +INSTALL_SHLIB = @INSTALL_SHLIB@ + +SHLIB = libelf$(SHLIB_SFX) +SHLINK = libelf$(SHLINK_SFX) +SONAME = libelf$(SONAME_SFX) + +# install includes in includedir? +DO_COMPAT = @DO_COMPAT@ + +COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) + +# no user serviceable parts below + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ +MAJOR = @MAJOR@ + +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +topdir = .. +subdir = lib + +.SUFFIXES: +.SUFFIXES: .c .o +.c.o: + @$(RM) $@ $(@:.o=.os) + if test -n "$(PICFLAGS)"; then \ + $(COMPILE) $(PICFLAGS) $< && $(MV) $@ $(@:.o=.os); \ + else true; fi + $(COMPILE) $< + +INCLUDES = -I$(topdir) -I. -I$(srcdir) + +# generic sources +SRCS1 = begin.c cntl.c end.c errmsg.c errno.c fill.c flag.c getarhdr.c \ + getarsym.c getbase.c getdata.c getident.c getscn.c hash.c kind.c \ + ndxscn.c newdata.c newscn.c next.c nextscn.c rand.c rawdata.c \ + rawfile.c strptr.c update.c version.c checksum.c +OBJS1 = begin.o cntl.o end.o errmsg.o errno.o fill.o flag.o getarhdr.o \ + getarsym.o getbase.o getdata.o getident.o getscn.o hash.o kind.o \ + ndxscn.o newdata.o newscn.o next.o nextscn.o rand.o rawdata.o \ + rawfile.o strptr.o update.o version.o checksum.o + +# 32-bit sources +SRCS2 = 32.fsize.c 32.getehdr.c 32.getphdr.c 32.getshdr.c 32.newehdr.c \ + 32.newphdr.c 32.xlatetof.c +OBJS2 = 32.fsize.o 32.getehdr.o 32.getphdr.o 32.getshdr.o 32.newehdr.o \ + 32.newphdr.o 32.xlatetof.o + +# support +SRCS3 = cook.c data.c input.c assert.c +OBJS3 = cook.o data.o input.o assert.o + +# nlist +SRCS4 = nlist.c +OBJS4 = nlist.o + +# opt +SRCS5 = opt.delscn.c x.remscn.c x.movscn.c x.elfext.c +OBJS5 = opt.delscn.o x.remscn.o x.movscn.o x.elfext.o + +# 64-bit sources +SRCS64 = 64.xlatetof.c gelfehdr.c gelfphdr.c gelfshdr.c gelftrans.c swap64.c +OBJS64 = 64.xlatetof.o gelfehdr.o gelfphdr.o gelfshdr.o gelftrans.o swap64.o + +# Versioning sources +SRCS_V = verdef_32_tof.c verdef_32_tom.c verdef_64_tof.c verdef_64_tom.c +OBJS_V = verdef_32_tof.o verdef_32_tom.o verdef_64_tof.o verdef_64_tom.o +HDRS_V = verdef.h verneed.h + +SRCS = $(SRCS1) $(SRCS2) $(SRCS3) $(SRCS4) $(SRCS5) $(SRCS64) $(SRCS_V) +OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS64) $(OBJS_V) + +# missing functions +LIBSRCS = memset.c +LIBOBJS = @LIBOBJS@ + +# public header files +HDRS = libelf.h nlist.h gelf.h + +# public header files (created by configure) +AUXHDRS = sys_elf.h + +# private header files +PRIVHDRS = byteswap.h errors.h ext_types.h private.h elf_repl.h \ + $(HDRS_V) + +DISTFILES = $(SRCS) $(LIBSRCS) $(HDRS) $(PRIVHDRS) Makefile.in sys_elf.h.in \ + Makefile.w32 build.bat config.h.w32 libelf.def sys_elf.h.w32 + +all: libelf.a shared-$(DO_SHLIB) + +check: + +shared-yes: $(SHLIB) +shared-no: + +libelf.a: $(OBJS) $(LIBOBJS) + @$(RM) $@ + $(AR) rcv $@ $(OBJS) $(LIBOBJS) + $(RANLIB) $@ + +$(SHLIB): libelf.a + @$(RM) $(SHLIB) + $(LINK_SHLIB) -o $(SHLIB) $(OBJS:.o=.os) $(LIBOBJS:.o=.os) $(DEPSHLIBS) + if test "$(SONAME)" = "$(SHLIB)"; then true; else \ + $(RM) $(SONAME) && $(LN_S) $(SHLIB) $(SONAME); \ + fi + if test "$(SHLINK)" = "$(SHLIB)"; then true; else \ + $(RM) $(SHLINK) && $(LN_S) $(SHLIB) $(SHLINK); \ + fi + +install: install-data \ + install-shared-$(DO_SHLIB) install-compat-$(DO_COMPAT) + +installdirs: $(top_srcdir)/mkinstalldirs + dirs="$(installdirs)"; for dir in $$dirs; do \ + $(SHELL) $(top_srcdir)/mkinstalldirs $(instroot)$$dir; \ + done + +install-data: all installdirs + $(INSTALL_DATA) libelf.a $(instroot)$(libdir) + -cd $(instroot)$(libdir) && $(RANLIB) libelf.a + files="$(HDRS) $(AUXHDRS) elf_repl.h"; for file in $$files; do \ + if test -r $$file; then \ + $(INSTALL_DATA) $$file $(instroot)$(includedir)/libelf; \ + else \ + $(INSTALL_DATA) $(srcdir)/$$file $(instroot)$(includedir)/libelf; \ + fi; \ + done + +uninstall: uninstall-data \ + uninstall-shared-$(DO_SHLIB) uninstall-compat-$(DO_COMPAT) + +uninstall-data: + $(RM) $(instroot)$(libdir)/libelf.a + $(RM) -r $(instroot)$(includedir)/libelf + +install-shared-yes: install-shared +install-shared-no: +install-shared: installdirs $(SHLIB) + $(INSTALL_SHLIB) $(SHLIB) $(instroot)$(libdir) + if test "$(SONAME)" = "$(SHLIB)"; then true; else \ + cd $(instroot)$(libdir) && $(RM) $(SONAME) && $(LN_S) $(SHLIB) $(SONAME); \ + fi + if test "$(SHLINK)" = "$(SHLIB)"; then true; else \ + cd $(instroot)$(libdir) && $(RM) $(SHLINK) && $(LN_S) $(SHLIB) $(SHLINK); \ + fi + +uninstall-shared-yes: uninstall-shared +uninstall-shared-no: +uninstall-shared: + cd $(instroot)$(libdir) && $(RM) $(SHLIB) $(SONAME) $(SHLINK) + +install-compat-yes: install-compat +install-compat-no: +install-compat: installdirs + files="$(HDRS)"; for file in $$files; do \ + if test -f $(instroot)$(includedir)/$$file; then true; else \ + echo "#include " > $(instroot)$(includedir)/$$file; \ + fi; \ + done + +uninstall-compat-yes: uninstall-compat +uninstall-compat-no: +uninstall-compat: + files="$(HDRS)"; for file in $$files; do \ + if grep "^#include \$$" $(instroot)$(includedir)/$$file >/dev/null 2>&1; then \ + $(RM) $(instroot)$(includedir)/$$file; \ + else true; fi; \ + done + +mostlyclean: + $(RM) *.o *.a *.os $(SHLIB) $(SONAME) $(SHLINK) + $(RM) *~ core a.out errlist + +clean: mostlyclean + +distclean: clean + $(RM) stamp-h $(AUXHDRS) + $(RM) Makefile + +maintainer-clean: distclean + +# maintainer only + +MAINT = @MAINT@ + +distdir = $(PACKAGE)-$(VERSION) +distsubdir = $(topdir)/$(distdir)/$(subdir) +$(MAINT)dist: $(DISTFILES) + if test -d $(distsubdir); then true; else mkdir $(distsubdir); fi + files="$(DISTFILES)"; for file in $$files; do \ + ln $(srcdir)/$$file $(distsubdir) || \ + cp -p $(srcdir)/$$file $(distsubdir) || exit 1; \ + done + +# For the justification of the following Makefile rules, see node +# `Automatic Remaking' in GNU Autoconf documentation. + +$(MAINT)Makefile: Makefile.in $(topdir)/config.status + cd $(topdir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status + +$(MAINT)sys_elf.h: stamp-h +$(MAINT)stamp-h: sys_elf.h.in $(topdir)/config.status + cd $(topdir) && CONFIG_FILES= CONFIG_HEADERS=$(subdir)/sys_elf.h ./config.status + $(RM) stamp-h && echo timestamp > stamp-h + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +# dependencies +$(OBJS): private.h $(topdir)/config.h libelf.h gelf.h errors.h $(AUXHDRS) +32.fsize.o: ext_types.h +32.xlatetof.o: byteswap.h ext_types.h +64.xlatetof.o: byteswap.h ext_types.h +getarsym.o: byteswap.h +memset.o: $(topdir)/config.h +nlist.o: nlist.h +swap64.o: byteswap.h +$(OBJS_V): byteswap.h ext_types.h $(HDRS_V) diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/Makefile.w32 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/Makefile.w32 Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,166 @@ +# lib/Makefile.w32 - Makefile for W32 port. +# Copyright (C) 1995 - 2006 Michael Riepe +# +# This library 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 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# @(#) $Id: Makefile.w32,v 1.2 2006/11/21 20:21:12 michael Exp $ + +instroot = + +prefix = +exec_prefix = +libdir = +includedir = +installdirs = $(libdir) $(includedir) $(includedir)/libelf + +CC = cl /nologo +LD = link /nologo +AR = +MV = +RM = del +LN_S = +RANLIB = +INSTALL = +INSTALL_DATA = +INSTALL_PROGRAM = + +CFLAGS = /O2 /W2 /TC /MD +CPPFLAGS = +DEFS = /DHAVE_CONFIG_H +LDFLAGS = +LIBS = +DEPSHLIBS = + +DO_SHLIB = +PICFLAGS = +SHLIB_SFX = .dll +SHLINK_SFX = +SONAME_SFX = +LINK_SHLIB = $(LD) /DLL $(LDFLAGS) + +SHLIB = libelf$(SHLIB_SFX) +SHLINK = libelf$(SHLINK_SFX) +SONAME = libelf$(SONAME_SFX) + +# install includes in includedir? +DO_COMPAT = + +INCLUDES = /I. + +COMPILE = $(CC) /c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) + +# no user serviceable parts below + +PACKAGE = libelf +VERSION = 0.8.9 +MAJOR = 0 + +SHELL = /bin/sh + +srcdir = . +top_srcdir = .. + +topdir = .. +subdir = lib + +.SUFFIXES: +.SUFFIXES: .obj .c +.c.obj: + $(COMPILE) $< + +# generic sources +SRCS1 = begin.c cntl.c end.c errmsg.c errno.c fill.c flag.c getarhdr.c \ + getarsym.c getbase.c getdata.c getident.c getscn.c hash.c kind.c \ + ndxscn.c newdata.c newscn.c next.c nextscn.c rand.c rawdata.c \ + rawfile.c strptr.c update.c version.c checksum.c +OBJS1 = $(SRCS1:.c=.obj) + +# 32-bit sources +SRCS2 = 32.fsize.c 32.getehdr.c 32.getphdr.c 32.getshdr.c 32.newehdr.c \ + 32.newphdr.c 32.xlatetof.c +OBJS2 = $(SRCS2:.c=.obj) + +# support +SRCS3 = cook.c data.c input.c assert.c +OBJS3 = $(SRCS3:.c=.obj) + +# nlist +SRCS4 = nlist.c +OBJS4 = $(SRCS4:.c=.obj) + +# opt +SRCS5 = opt.delscn.c x.remscn.c x.movscn.c x.elfext.c +OBJS5 = $(SRCS5:.c=.obj) + +# 64-bit sources +SRCS64 = 64.xlatetof.c gelfehdr.c gelfphdr.c gelfshdr.c gelftrans.c swap64.c +OBJS64 = $(SRCS64:.c=.obj) + +# Versioning sources +SRCS_V = verdef_32_tof.c verdef_32_tom.c verdef_64_tof.c verdef_64_tom.c +OBJS_V = $(SRCS_V:.c=.obj) +HDRS_V = verdef.h verneed.h + +SRCS = $(SRCS1) $(SRCS2) $(SRCS3) $(SRCS4) $(SRCS5) $(SRCS64) $(SRCS_V) +OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS64) $(OBJS_V) + +# missing functions +LIBSRCS = memset.c +LIBOBJS = + +# public header files +HDRS = libelf.h nlist.h gelf.h + +# public header files (created by configure) +AUXHDRS = sys_elf.h + +# private header files +PRIVHDRS = byteswap.h errors.h ext_types.h private.h elf_repl.h $(HDRS_V) + +DISTFILES = $(SRCS) $(LIBSRCS) $(HDRS) $(PRIVHDRS) Makefile.in sys_elf.h.in + +all: $(OBJS) $(SHLIB) + +check: + +$(SHLIB): libelf.def $(OBJS) $(LIBOBJS) + -@$(RM) $(SHLIB) + $(LINK_SHLIB) /OUT:"$(SHLIB)" /DEF:"libelf.def" $(OBJS) $(LIBOBJS) kernel32.lib + +install: + +mostlyclean: + -$(RM) *.obj + -$(RM) $(SHLIB) + -$(RM) libelf.lib + -$(RM) libelf.exp + +clean: mostlyclean + +distclean: clean + -$(RM) $(AUXHDRS) + +maintainer-clean: distclean + +# dependencies +$(OBJS): private.h config.h libelf.h gelf.h errors.h $(AUXHDRS) +32.fsize.obj: ext_types.h +32.xlatetof.obj: byteswap.h ext_types.h +64.xlatetof.obj: byteswap.h ext_types.h +getarsym.obj: byteswap.h +memset.obj: config.h +nlist.obj: nlist.h +swap64.obj: byteswap.h +$(OBJS_V): byteswap.h ext_types.h $(HDRS_V) diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/assert.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/assert.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,33 @@ +/* +assert.c - assert function for libelf. +Copyright (C) 1999 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: assert.c,v 1.4 2005/05/21 15:39:20 michael Exp $"; +#endif /* lint */ + +#include + +void +__elf_assert(const char *file, unsigned line, const char *cond) { + fprintf(stderr, "%s:%u: libelf assertion failure: %s\n", + file, line, cond); + abort(); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/begin.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/begin.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,450 @@ +/* + * begin.c - implementation of the elf_begin(3) and elf_memory(3) functions. + * Copyright (C) 1995 - 2004 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: begin.c,v 1.20 2006/08/17 23:59:58 michael Exp $"; +#endif /* lint */ + +#if HAVE_AR_H +#include +#else /* HAVE_AR_H */ + +#define ARMAG "!\n" +#define SARMAG 8 + +struct ar_hdr { + char ar_name[16]; + char ar_date[12]; + char ar_uid[6]; + char ar_gid[6]; + char ar_mode[8]; + char ar_size[10]; + char ar_fmag[2]; +}; + +#define ARFMAG "`\n" + +#endif /* HAVE_AR_H */ + +static const Elf _elf_init = INIT_ELF; +static const char fmag[] = ARFMAG; + +static unsigned long +getnum(const char *str, size_t len, int base, size_t *err) { + unsigned long result = 0; + + while (len && *str == ' ') { + str++; len--; + } + while (len && *str >= '0' && (*str - '0') < base) { + result = base * result + *str++ - '0'; len--; + } + while (len && *str == ' ') { + str++; len--; + } + if (len) { + *err = len; + } + return result; +} + +static void +_elf_init_ar(Elf *elf) { + struct ar_hdr *hdr; + size_t offset; + size_t size; + size_t err = 0; + + elf->e_kind = ELF_K_AR; + elf->e_idlen = SARMAG; + elf->e_off = SARMAG; + + /* process special members */ + offset = SARMAG; + while (!elf->e_strtab && offset + sizeof(*hdr) <= elf->e_size) { + hdr = (struct ar_hdr*)(elf->e_data + offset); + if (memcmp(hdr->ar_fmag, fmag, sizeof(fmag) - 1)) { + break; + } + if (hdr->ar_name[0] != '/') { + break; + } + size = getnum(hdr->ar_size, sizeof(hdr->ar_size), 10, &err); + if (err || !size) { + break; + } + offset += sizeof(*hdr); + if (offset + size > elf->e_size) { + break; + } + if (hdr->ar_name[1] == '/' && hdr->ar_name[2] == ' ') { + elf->e_strtab = elf->e_data + offset; + elf->e_strlen = size; + break; + } + if (hdr->ar_name[1] != ' ') { + break; + } + /* + * Windows (.lib) archives provide two symbol tables + * The first one is the one we want. + */ + if (!elf->e_symtab) { + elf->e_symtab = elf->e_data + offset; + elf->e_symlen = size; + } + offset += size + (size & 1); + } +} + +static Elf_Arhdr* +_elf_arhdr(Elf *arf) { + struct ar_hdr *hdr; + Elf_Arhdr *arhdr; + size_t namelen; + size_t tmp; + char *name; + size_t err = 0; + + if (arf->e_off == arf->e_size) { + /* no error! */ + return NULL; + } + if (arf->e_off < 0 || arf->e_off > arf->e_size) { + seterr(ERROR_OUTSIDE); + return NULL; + } + if (arf->e_off + sizeof(*hdr) > arf->e_size) { + seterr(ERROR_TRUNC_ARHDR); + return NULL; + } + elf_assert(arf->e_data != NULL); + hdr = (struct ar_hdr*)(arf->e_data + arf->e_off); + if (memcmp(hdr->ar_fmag, fmag, sizeof(fmag) - 1)) { + seterr(ERROR_ARFMAG); + return NULL; + } + + name = hdr->ar_name; + for (namelen = sizeof(hdr->ar_name); namelen > 0; namelen--) { + if (name[namelen - 1] != ' ') { + break; + } + } + if (name[0] == '/') { + if (name[1] >= '0' && name[1] <= '9') { + if (!arf->e_strtab) { + seterr(ERROR_ARSTRTAB); + return NULL; + } + tmp = getnum(&name[1], namelen - 1, 10, &err); + if (err) { + seterr(ERROR_ARSPECIAL); + return NULL; + } + if (tmp < 0 || tmp >= arf->e_strlen) { + seterr(ERROR_ARSTRTAB); + return NULL; + } + for (namelen = tmp; namelen < arf->e_strlen; namelen++) { + if (arf->e_strtab[namelen] == '/') { + break; + } + } + if (namelen == arf->e_strlen) { + seterr(ERROR_ARSTRTAB); + return NULL; + } + name = arf->e_strtab + tmp; + namelen -= tmp; + } + else if (namelen != 1 && !(namelen == 2 && name[1] == '/')) { + seterr(ERROR_ARSPECIAL); + return NULL; + } + } + else if (namelen > 0 && name[namelen - 1] == '/') { + namelen--; + } + /* XXX some broken software omits the trailing slash + else { + namelen = 0; + } + */ + + if (!(arhdr = (Elf_Arhdr*)malloc(sizeof(*arhdr) + + sizeof(hdr->ar_name) + namelen + 2))) { + seterr(ERROR_MEM_ARHDR); + return NULL; + } + + arhdr->ar_name = NULL; + arhdr->ar_rawname = (char*)(arhdr + 1); + arhdr->ar_date = getnum(hdr->ar_date, sizeof(hdr->ar_date), 10, &err); + arhdr->ar_uid = getnum(hdr->ar_uid, sizeof(hdr->ar_uid), 10, &err); + arhdr->ar_gid = getnum(hdr->ar_gid, sizeof(hdr->ar_gid), 10, &err); + arhdr->ar_mode = getnum(hdr->ar_mode, sizeof(hdr->ar_mode), 8, &err); + arhdr->ar_size = getnum(hdr->ar_size, sizeof(hdr->ar_size), 10, &err); + if (err) { + free(arhdr); + seterr(ERROR_ARHDR); + return NULL; + } + if (arf->e_off + sizeof(struct ar_hdr) + arhdr->ar_size > arf->e_size) { + free(arhdr); + seterr(ERROR_TRUNC_MEMBER); + return NULL; + } + + memcpy(arhdr->ar_rawname, hdr->ar_name, sizeof(hdr->ar_name)); + arhdr->ar_rawname[sizeof(hdr->ar_name)] = '\0'; + + if (namelen) { + arhdr->ar_name = arhdr->ar_rawname + sizeof(hdr->ar_name) + 1; + memcpy(arhdr->ar_name, name, namelen); + arhdr->ar_name[namelen] = '\0'; + } + + return arhdr; +} + +static void +_elf_check_type(Elf *elf, size_t size) { + elf->e_idlen = size; + if (size >= EI_NIDENT && !memcmp(elf->e_data, ELFMAG, SELFMAG)) { + elf->e_kind = ELF_K_ELF; + elf->e_idlen = EI_NIDENT; + elf->e_class = elf->e_data[EI_CLASS]; + elf->e_encoding = elf->e_data[EI_DATA]; + elf->e_version = elf->e_data[EI_VERSION]; + } + else if (size >= SARMAG && !memcmp(elf->e_data, ARMAG, SARMAG)) { + _elf_init_ar(elf); + } +} + +Elf* +elf_begin(int fd, Elf_Cmd cmd, Elf *ref) { + Elf_Arhdr *arhdr = NULL; + size_t size = 0; + off_t off; + Elf *elf; + + elf_assert(_elf_init.e_magic == ELF_MAGIC); + if (_elf_version == EV_NONE) { + seterr(ERROR_VERSION_UNSET); + return NULL; + } + else if (cmd == ELF_C_NULL) { + return NULL; + } + else if (cmd == ELF_C_WRITE) { + ref = NULL; + } + else if (cmd != ELF_C_READ && cmd != ELF_C_RDWR) { + seterr(ERROR_INVALID_CMD); + return NULL; + } + else if (ref) { + elf_assert(ref->e_magic == ELF_MAGIC); + if (!ref->e_readable || (cmd == ELF_C_RDWR && !ref->e_writable)) { + seterr(ERROR_CMDMISMATCH); + return NULL; + } + if (ref->e_kind != ELF_K_AR) { + ref->e_count++; + return ref; + } + if (cmd == ELF_C_RDWR) { + seterr(ERROR_MEMBERWRITE); + return NULL; + } + if (ref->e_memory) { + fd = ref->e_fd; + } + else if (fd != ref->e_fd) { + seterr(ERROR_FDMISMATCH); + return NULL; + } + if (!(arhdr = _elf_arhdr(ref))) { + return NULL; + } + size = arhdr->ar_size; + } + else if ((off = lseek(fd, (off_t)0, SEEK_END)) == (off_t)-1 + || (off_t)(size = off) != off) { + seterr(ERROR_IO_GETSIZE); + return NULL; + } + + if (!(elf = (Elf*)malloc(sizeof(Elf)))) { + seterr(ERROR_MEM_ELF); + return NULL; + } + *elf = _elf_init; + elf->e_fd = fd; + elf->e_parent = ref; + elf->e_size = elf->e_dsize = size; + + if (cmd != ELF_C_READ) { + elf->e_writable = 1; + } + if (cmd != ELF_C_WRITE) { + elf->e_readable = 1; + } + else { + return elf; + } + + if (ref) { + size_t offset = ref->e_off + sizeof(struct ar_hdr); + Elf *xelf; + + elf_assert(arhdr); + elf->e_arhdr = arhdr; + elf->e_base = ref->e_base + offset; + /* + * Share the archive's memory image. To avoid + * multiple independent elf descriptors if the + * same member is requested twice, scan the list + * of open members for duplicates. + * + * I don't know how SVR4 handles this case. Don't rely on it. + */ + for (xelf = ref->e_members; xelf; xelf = xelf->e_link) { + elf_assert(xelf->e_parent == ref); + if (xelf->e_base == elf->e_base) { + free(arhdr); + free(elf); + xelf->e_count++; + return xelf; + } + } + if (size == 0) { + elf->e_data = NULL; + } +#if 1 + else { + /* + * Archive members may be misaligned. Freezing them will + * cause libelf to allocate buffers for translated data, + * which should be properly aligned in all cases. + */ + elf_assert(!ref->e_cooked); + elf->e_data = elf->e_rawdata = ref->e_data + offset; + } +#else + else if (ref->e_data == ref->e_rawdata) { + elf_assert(!ref->e_cooked); + /* + * archive is frozen - freeze member, too + */ + elf->e_data = elf->e_rawdata = ref->e_data + offset; + } + else { + elf_assert(!ref->e_memory); + elf->e_data = ref->e_data + offset; + /* + * The member's memory image may have been modified if + * the member has been processed before. Since we need the + * original image, we have to re-read the archive file. + * Will fail if the archive's file descriptor is disabled. + */ + if (!ref->e_cooked) { + ref->e_cooked = 1; + } + else if (!_elf_read(ref, elf->e_data, offset, size)) { + free(arhdr); + free(elf); + return NULL; + } + } +#endif + elf->e_next = offset + size + (size & 1); + elf->e_disabled = ref->e_disabled; + elf->e_memory = ref->e_memory; + /* parent/child linking */ + elf->e_link = ref->e_members; + ref->e_members = elf; + ref->e_count++; + /* Slowaris compatibility - do not rely on this! */ + ref->e_off = elf->e_next; + } + else if (size) { +#if HAVE_MMAP + /* + * Using mmap on writable files will interfere with elf_update + */ + if (!elf->e_writable && (elf->e_data = _elf_mmap(elf))) { + elf->e_unmap_data = 1; + } + else +#endif /* HAVE_MMAP */ + if (!(elf->e_data = _elf_read(elf, NULL, 0, size))) { + free(elf); + return NULL; + } + } + + _elf_check_type(elf, size); + return elf; +} + +Elf* +elf_memory(char *image, size_t size) { + Elf *elf; + + elf_assert(_elf_init.e_magic == ELF_MAGIC); + if (_elf_version == EV_NONE) { + seterr(ERROR_VERSION_UNSET); + return NULL; + } + else if (size == 0 || image == NULL) { + /* TODO: set error code? */ + return NULL; + } + + if (!(elf = (Elf*)malloc(sizeof(Elf)))) { + seterr(ERROR_MEM_ELF); + return NULL; + } + *elf = _elf_init; + elf->e_size = elf->e_dsize = size; + elf->e_data = elf->e_rawdata = image; + elf->e_readable = 1; + elf->e_disabled = 1; + elf->e_memory = 1; + + _elf_check_type(elf, size); + return elf; +} + +#if __LIBELF64 + +int +gelf_getclass(Elf *elf) { + if (elf && elf->e_kind == ELF_K_ELF && valid_class(elf->e_class)) { + return elf->e_class; + } + return ELFCLASSNONE; +} + +#endif /* __LIBELF64 */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/build.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/build.bat Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,36 @@ +@echo off + +rem lib/build.bat - build script for W32 port +rem Copyright (C) 2004 - 2006 Michael Riepe +rem +rem This library is free software; you can redistribute it and/or +rem modify it under the terms of the GNU Library General Public +rem License as published by the Free Software Foundation; either +rem version 2 of the License, or (at your option) any later version. +rem +rem This library is distributed in the hope that it will be useful, +rem but WITHOUT ANY WARRANTY; without even the implied warranty of +rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +rem Library General Public License for more details. +rem +rem You should have received a copy of the GNU Library General Public +rem License along with this library; if not, write to the Free Software +rem Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +rem @(#) $Id: build.bat,v 1.1 2006/08/21 18:03:48 michael Exp $ + +rem *** BEGIN EDIT HERE *** +rem Please uncomment the line that suits your system: +rem call "C:\Program Files\Microsoft Visual Studio\VC98\bin\vcvars32.bat" +rem call "C:\Program Files\Microsoft Visual Studio 8\VC\bin\vcvars32.bat" +rem call "C:\Programme\Microsoft Visual Studio\VC98\bin\vcvars32.bat" +rem call "C:\Programme\Microsoft Visual Studio 8\VC\bin\vcvars32.bat" +rem OR, if you have to set the path to the compiler directly: +rem set PATH="C:\PATH\TO\COMPILER\BINARY;%PATH%" +rem Of course, you'll have to enter the correct path above. +rem You may also have to change CC (default: cl.exe) in Makefile.w32. +rem *** END EDIT HERE *** + +copy config.h.w32 config.h +copy sys_elf.h.w32 sys_elf.h +nmake /nologo /f Makefile.w32 %1 diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/byteswap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/byteswap.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,95 @@ +/* +byteswap.h - functions and macros for byte swapping. +Copyright (C) 1995 - 2001 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* @(#) $Id: byteswap.h,v 1.6 2005/05/21 15:39:20 michael Exp $ */ + +#ifndef _BYTESWAP_H +#define _BYTESWAP_H + +#define lu(from,i,s) (((__libelf_u32_t)((unsigned char*)(from))[i])<<(s)) +#define li(from,i,s) (((__libelf_i32_t)(( signed char*)(from))[i])<<(s)) + +#define __load_u16L(from) ((__libelf_u32_t) \ + (lu(from,1,8) | lu(from,0,0))) +#define __load_u16M(from) ((__libelf_u32_t) \ + (lu(from,0,8) | lu(from,1,0))) +#define __load_i16L(from) ((__libelf_i32_t) \ + (li(from,1,8) | lu(from,0,0))) +#define __load_i16M(from) ((__libelf_i32_t) \ + (li(from,0,8) | lu(from,1,0))) + +#define __load_u32L(from) ((__libelf_u32_t) \ + (lu(from,3,24) | lu(from,2,16) | lu(from,1,8) | lu(from,0,0))) +#define __load_u32M(from) ((__libelf_u32_t) \ + (lu(from,0,24) | lu(from,1,16) | lu(from,2,8) | lu(from,3,0))) +#define __load_i32L(from) ((__libelf_i32_t) \ + (li(from,3,24) | lu(from,2,16) | lu(from,1,8) | lu(from,0,0))) +#define __load_i32M(from) ((__libelf_i32_t) \ + (li(from,0,24) | lu(from,1,16) | lu(from,2,8) | lu(from,3,0))) + +#define su(to,i,v,s) (((char*)(to))[i]=((__libelf_u32_t)(v)>>(s))) +#define si(to,i,v,s) (((char*)(to))[i]=((__libelf_i32_t)(v)>>(s))) + +#define __store_u16L(to,v) \ + (su(to,1,v,8), su(to,0,v,0)) +#define __store_u16M(to,v) \ + (su(to,0,v,8), su(to,1,v,0)) +#define __store_i16L(to,v) \ + (si(to,1,v,8), si(to,0,v,0)) +#define __store_i16M(to,v) \ + (si(to,0,v,8), si(to,1,v,0)) + +#define __store_u32L(to,v) \ + (su(to,3,v,24), su(to,2,v,16), su(to,1,v,8), su(to,0,v,0)) +#define __store_u32M(to,v) \ + (su(to,0,v,24), su(to,1,v,16), su(to,2,v,8), su(to,3,v,0)) +#define __store_i32L(to,v) \ + (si(to,3,v,24), si(to,2,v,16), si(to,1,v,8), si(to,0,v,0)) +#define __store_i32M(to,v) \ + (si(to,0,v,24), si(to,1,v,16), si(to,2,v,8), si(to,3,v,0)) + +#if __LIBELF64 + +/* + * conversion functions from swap64.c + */ +extern __libelf_u64_t _elf_load_u64L(const unsigned char *from); +extern __libelf_u64_t _elf_load_u64M(const unsigned char *from); +extern __libelf_i64_t _elf_load_i64L(const unsigned char *from); +extern __libelf_i64_t _elf_load_i64M(const unsigned char *from); +extern void _elf_store_u64L(unsigned char *to, __libelf_u64_t v); +extern void _elf_store_u64M(unsigned char *to, __libelf_u64_t v); +extern void _elf_store_i64L(unsigned char *to, __libelf_u64_t v); +extern void _elf_store_i64M(unsigned char *to, __libelf_u64_t v); + +/* + * aliases for existing conversion code + */ +#define __load_u64L _elf_load_u64L +#define __load_u64M _elf_load_u64M +#define __load_i64L _elf_load_i64L +#define __load_i64M _elf_load_i64M +#define __store_u64L _elf_store_u64L +#define __store_u64M _elf_store_u64M +#define __store_i64L _elf_store_i64L +#define __store_i64M _elf_store_i64M + +#endif /* __LIBELF64 */ + +#endif /* _BYTESWAP_H */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/checksum.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/checksum.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,178 @@ +/* +checksum.c - implementation of the elf{32,64}_checksum(3) functions. +Copyright (C) 1995 - 2001 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: checksum.c,v 1.6 2005/05/21 15:39:20 michael Exp $"; +#endif /* lint */ + +/* + * Compatibility note: + * + * The algorithm used in {elf32,elf64,gelf}_checksum() does not seem to + * be documented. I hope I got it right. My implementation does the + * following: + * + * - skip sections that do not have the SHF_ALLOC flag set + * - skip sections of type SHT_NULL, SHT_NOBITS, SHT_DYNSYM and + * SHT_DYNAMIC + * - add all data bytes from the remaining sections, modulo 2**32 + * - add upper and lower half of the result + * - subtract 0xffff if the result is > 0xffff + * - if any error occurs, return 0L + */ + +static int +skip_section(Elf_Scn *scn, unsigned cls) { + if (cls == ELFCLASS32) { + Elf32_Shdr *shdr = &scn->s_shdr32; + + if (!(shdr->sh_flags & SHF_ALLOC)) { + return 1; + } + switch (shdr->sh_type) { + case SHT_NULL: + case SHT_NOBITS: + /* Solaris seems to ignore these, too */ + case SHT_DYNSYM: + case SHT_DYNAMIC: + return 1; + } + } +#if __LIBELF64 + else if (cls == ELFCLASS64) { + Elf64_Shdr *shdr = &scn->s_shdr64; + + if (!(shdr->sh_flags & SHF_ALLOC)) { + return 1; + } + switch (shdr->sh_type) { + case SHT_NULL: + case SHT_NOBITS: + /* Solaris seems to ignore these, too */ + case SHT_DYNSYM: + case SHT_DYNAMIC: + return 1; + } + } +#endif /* __LIBELF64 */ + else { + seterr(ERROR_UNIMPLEMENTED); + } + return 0; +} + +static long +add_bytes(unsigned char *ptr, size_t len) { + long csum = 0; + + while (len--) { + csum += *ptr++; + } + return csum; +} + +static long +_elf_csum(Elf *elf) { + long csum = 0; + Elf_Data *data; + Elf_Scn *scn; + + if (!elf->e_ehdr && !_elf_cook(elf)) { + /* propagate errors from _elf_cook */ + return 0L; + } + seterr(0); + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + if (scn->s_index == SHN_UNDEF || skip_section(scn, elf->e_class)) { + continue; + } + data = NULL; + while ((data = elf_getdata(scn, data))) { + if (data->d_size) { + if (data->d_buf == NULL) { + seterr(ERROR_NULLBUF); + return 0L; + } + csum += add_bytes(data->d_buf, data->d_size); + } + } + } + if (_elf_errno) { + return 0L; + } + csum = (csum & 0xffff) + ((csum >> 16) & 0xffff); + if (csum > 0xffff) { + csum -= 0xffff; + } + return csum; +} + +long +elf32_checksum(Elf *elf) { + if (elf) { + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_class != ELFCLASS32) { + seterr(ERROR_CLASSMISMATCH); + } + else { + return _elf_csum(elf); + } + } + return 0L; +} + +#if __LIBELF64 + +long +elf64_checksum(Elf *elf) { + if (elf) { + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_class != ELFCLASS64) { + seterr(ERROR_CLASSMISMATCH); + } + else { + return _elf_csum(elf); + } + } + return 0L; +} + +long +gelf_checksum(Elf *elf) { + if (elf) { + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (!valid_class(elf->e_class)) { + seterr(ERROR_UNKNOWN_CLASS); + } + else { + return _elf_csum(elf); + } + } + return 0L; +} + +#endif /* __LIBELF64 */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/cntl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/cntl.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,71 @@ +/* +cntl.c - implementation of the elf_cntl(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: cntl.c,v 1.6 2005/05/21 15:39:21 michael Exp $"; +#endif /* lint */ + +int +elf_cntl(Elf *elf, Elf_Cmd cmd) { + Elf_Scn *scn; + Elf *child; + + if (!elf) { + return -1; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (cmd == ELF_C_FDREAD) { + if (!elf->e_readable) { + seterr(ERROR_WRONLY); + return -1; + } + } + else if (cmd != ELF_C_FDDONE) { + seterr(ERROR_INVALID_CMD); + return -1; + } + if (elf->e_disabled) { + return 0; + } + if (elf->e_kind == ELF_K_AR) { + for (child = elf->e_members; child; child = child->e_link) { + elf_assert(elf == child->e_parent); + if (elf_cntl(child, cmd)) { + return -1; + } + } + } + else if (elf->e_kind == ELF_K_ELF && cmd == ELF_C_FDREAD) { + if (!elf->e_ehdr && !_elf_cook(elf)) { + return -1; + } + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + if (scn->s_index == SHN_UNDEF || scn->s_type == SHT_NULL) { + continue; + } + else if (!elf_getdata(scn, NULL)) { + return -1; + } + } + } + elf->e_disabled = 1; + return 0; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/config.h.w32 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/config.h.w32 Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,161 @@ +/* + * lib/config.h.w32 - configuration file for W32 port + * Copyright (C) 2004 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @(#) $Id: config.h.w32,v 1.2 2006/09/07 15:55:42 michael Exp $ + */ + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define to `long' if doesn't define. */ +#undef off_t + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you want to include extra debugging code */ +#define ENABLE_DEBUG 1 + +/* Define if memmove() does not copy overlapping arrays correctly */ +#undef HAVE_BROKEN_MEMMOVE + +/* Define if you have the catgets function. */ +#undef HAVE_CATGETS + +/* Define if you have the dgettext function. */ +#undef HAVE_DGETTEXT + +/* Define if you have the memset function. */ +#define HAVE_MEMSET 1 + +/* Define if struct nlist is declared in or */ +#undef HAVE_STRUCT_NLIST_DECLARATION + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_LINK_H + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_SYS_LINK_H + +/* Define to `' or `' if one of them is present */ +#undef __LIBELF_HEADER_ELF_H + +/* Define if you want 64-bit support (and your system supports it) */ +#define __LIBELF64 1 + +/* Define if you want 64-bit support, and are running IRIX */ +#undef __LIBELF64_IRIX + +/* Define if you want 64-bit support, and are running Linux */ +#undef __LIBELF64_LINUX + +/* Define if you want symbol versioning (and your system supports it) */ +#define __LIBELF_SYMBOL_VERSIONS 1 + +/* Define if symbol versioning uses Sun section type (SHT_SUNW_*) */ +#define __LIBELF_SUN_SYMBOL_VERSIONS 1 + +/* Define if symbol versioning uses GNU section types (SHT_GNU_*) */ +#undef __LIBELF_GNU_SYMBOL_VERSIONS + +/* Define to a 64-bit signed integer type if one exists */ +#define __libelf_i64_t __int64 + +/* Define to a 64-bit unsigned integer type if one exists */ +#define __libelf_u64_t unsigned __int64 + +/* Define to a 32-bit signed integer type if one exists */ +#define __libelf_i32_t int + +/* Define to a 32-bit unsigned integer type if one exists */ +#define __libelf_u32_t unsigned int + +/* Define to a 16-bit signed integer type if one exists */ +#define __libelf_i16_t short int + +/* Define to a 16-bit unsigned integer type if one exists */ +#define __libelf_u16_t unsigned short int + +/* The number of bytes in a __int64. */ +#define SIZEOF___INT64 8 + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/* The number of bytes in a long long. */ +#define SIZEOF_LONG_LONG 0 + +/* The number of bytes in a short. */ +#define SIZEOF_SHORT 2 + +/* Define if you have the ftruncate function. */ +#undef HAVE_FTRUNCATE + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcmp function. */ +#define HAVE_MEMCMP 1 + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY 1 + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the memset function. */ +#define HAVE_MEMSET 1 + +/* Define if you have the header file. */ +#undef HAVE_AR_H + +/* Define if you have the header file. */ +#undef HAVE_ELF_H + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_GELF_H + +/* Define if you have the header file. */ +#undef HAVE_LIBELF_H + +/* Define if you have the header file. */ +#undef HAVE_LINK_H + +/* Define if you have the header file. */ +#undef HAVE_NLIST_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_ELF_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_LINK_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/cook.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/cook.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,501 @@ +/* + * cook.c - read and translate ELF files. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: cook.c,v 1.28 2006/07/07 22:15:50 michael Exp $"; +#endif /* lint */ + +const Elf_Scn _elf_scn_init = INIT_SCN; +const Scn_Data _elf_data_init = INIT_DATA; + +Elf_Type +_elf_scn_type(unsigned t) { + switch (t) { + case SHT_DYNAMIC: return ELF_T_DYN; + case SHT_DYNSYM: return ELF_T_SYM; + case SHT_HASH: return ELF_T_WORD; + case SHT_REL: return ELF_T_REL; + case SHT_RELA: return ELF_T_RELA; + case SHT_SYMTAB: return ELF_T_SYM; + case SHT_SYMTAB_SHNDX: return ELF_T_WORD; /* XXX: really? */ +#if __LIBELF_SYMBOL_VERSIONS +#if __LIBELF_SUN_SYMBOL_VERSIONS + case SHT_SUNW_verdef: return ELF_T_VDEF; + case SHT_SUNW_verneed: return ELF_T_VNEED; + case SHT_SUNW_versym: return ELF_T_HALF; +#else /* __LIBELF_SUN_SYMBOL_VERSIONS */ + case SHT_GNU_verdef: return ELF_T_VDEF; + case SHT_GNU_verneed: return ELF_T_VNEED; + case SHT_GNU_versym: return ELF_T_HALF; +#endif /* __LIBELF_SUN_SYMBOL_VERSIONS */ +#endif /* __LIBELF_SYMBOL_VERSIONS */ + } + return ELF_T_BYTE; +} + +/* + * Check for overflow on 32-bit systems + */ +#define overflow(a,b,t) (sizeof(a) < sizeof(t) && (t)(a) != (b)) + +#define truncerr(t) ((t)==ELF_T_EHDR?ERROR_TRUNC_EHDR: \ + ((t)==ELF_T_PHDR?ERROR_TRUNC_PHDR: \ + ERROR_INTERNAL)) +#define memerr(t) ((t)==ELF_T_EHDR?ERROR_MEM_EHDR: \ + ((t)==ELF_T_PHDR?ERROR_MEM_PHDR: \ + ERROR_INTERNAL)) + +Elf_Data* +_elf_xlatetom(const Elf *elf, Elf_Data *dst, const Elf_Data *src) { + if (elf->e_class == ELFCLASS32) { + return elf32_xlatetom(dst, src, elf->e_encoding); + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + return elf64_xlatetom(dst, src, elf->e_encoding); + } +#endif /* __LIBELF64 */ + seterr(ERROR_UNIMPLEMENTED); + return NULL; +} + +static char* +_elf_item(void *buf, Elf *elf, Elf_Type type, size_t off) { + Elf_Data src, dst; + + elf_assert(valid_type(type)); + if (off < 0 || off > elf->e_size) { + seterr(ERROR_OUTSIDE); + return NULL; + } + + src.d_type = type; + src.d_version = elf->e_version; + src.d_size = _fsize(elf->e_class, src.d_version, type); + elf_assert(src.d_size); + if ((elf->e_size - off) < src.d_size) { + seterr(truncerr(type)); + return NULL; + } + + dst.d_version = _elf_version; + dst.d_size = _msize(elf->e_class, dst.d_version, type); + elf_assert(dst.d_size); + + if (!(dst.d_buf = buf) && !(dst.d_buf = malloc(dst.d_size))) { + seterr(memerr(type)); + return NULL; + } + + elf_assert(elf->e_data); + if (elf->e_rawdata) { + src.d_buf = elf->e_rawdata + off; + } + else { + src.d_buf = elf->e_data + off; + } + + if (_elf_xlatetom(elf, &dst, &src)) { + return (char*)dst.d_buf; + } + if (dst.d_buf != buf) { + free(dst.d_buf); + } + return NULL; +} + +static int +_elf_cook_phdr(Elf *elf) { + size_t num, off, entsz; + + if (elf->e_class == ELFCLASS32) { + num = ((Elf32_Ehdr*)elf->e_ehdr)->e_phnum; + off = ((Elf32_Ehdr*)elf->e_ehdr)->e_phoff; + entsz = ((Elf32_Ehdr*)elf->e_ehdr)->e_phentsize; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + num = ((Elf64_Ehdr*)elf->e_ehdr)->e_phnum; + off = ((Elf64_Ehdr*)elf->e_ehdr)->e_phoff; + entsz = ((Elf64_Ehdr*)elf->e_ehdr)->e_phentsize; + /* + * Check for overflow on 32-bit systems + */ + if (overflow(off, ((Elf64_Ehdr*)elf->e_ehdr)->e_phoff, Elf64_Off)) { + seterr(ERROR_OUTSIDE); + return 0; + } + } +#endif /* __LIBELF64 */ + else { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + if (off) { + Elf_Scn *scn; + size_t size; + unsigned i; + char *p; + + if (num == PN_XNUM) { + /* + * Overflow in ehdr->e_phnum. + * Get real value from first SHDR. + */ + if (!(scn = elf->e_scn_1)) { + seterr(ERROR_NOSUCHSCN); + return 0; + } + if (elf->e_class == ELFCLASS32) { + num = scn->s_shdr32.sh_info; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + num = scn->s_shdr64.sh_info; + } +#endif /* __LIBELF64 */ + /* we already had this + else { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + */ + } + + size = _fsize(elf->e_class, elf->e_version, ELF_T_PHDR); + elf_assert(size); +#if ENABLE_EXTENDED_FORMAT + if (entsz < size) { +#else /* ENABLE_EXTENDED_FORMAT */ + if (entsz != size) { +#endif /* ENABLE_EXTENDED_FORMAT */ + seterr(ERROR_EHDR_PHENTSIZE); + return 0; + } + size = _msize(elf->e_class, _elf_version, ELF_T_PHDR); + elf_assert(size); + if (!(p = malloc(num * size))) { + seterr(memerr(ELF_T_PHDR)); + return 0; + } + for (i = 0; i < num; i++) { + if (!_elf_item(p + i * size, elf, ELF_T_PHDR, off + i * entsz)) { + free(p); + return 0; + } + } + elf->e_phdr = p; + elf->e_phnum = num; + } + return 1; +} + +static int +_elf_cook_shdr(Elf *elf) { + size_t num, off, entsz; + + if (elf->e_class == ELFCLASS32) { + num = ((Elf32_Ehdr*)elf->e_ehdr)->e_shnum; + off = ((Elf32_Ehdr*)elf->e_ehdr)->e_shoff; + entsz = ((Elf32_Ehdr*)elf->e_ehdr)->e_shentsize; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + num = ((Elf64_Ehdr*)elf->e_ehdr)->e_shnum; + off = ((Elf64_Ehdr*)elf->e_ehdr)->e_shoff; + entsz = ((Elf64_Ehdr*)elf->e_ehdr)->e_shentsize; + /* + * Check for overflow on 32-bit systems + */ + if (overflow(off, ((Elf64_Ehdr*)elf->e_ehdr)->e_shoff, Elf64_Off)) { + seterr(ERROR_OUTSIDE); + return 0; + } + } +#endif /* __LIBELF64 */ + else { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + if (off) { + struct tmp { + Elf_Scn scn; + Scn_Data data; + } *head; + Elf_Data src, dst; + Elf_Scn *scn; + Scn_Data *sd; + unsigned i; + + if (off < 0 || off > elf->e_size) { + seterr(ERROR_OUTSIDE); + return 0; + } + + src.d_type = ELF_T_SHDR; + src.d_version = elf->e_version; + src.d_size = _fsize(elf->e_class, src.d_version, ELF_T_SHDR); + elf_assert(src.d_size); +#if ENABLE_EXTENDED_FORMAT + if (entsz < src.d_size) { +#else /* ENABLE_EXTENDED_FORMAT */ + if (entsz != src.d_size) { +#endif /* ENABLE_EXTENDED_FORMAT */ + seterr(ERROR_EHDR_SHENTSIZE); + return 0; + } + dst.d_version = EV_CURRENT; + + if (num == 0) { + union { + Elf32_Shdr sh32; +#if __LIBELF64 + Elf64_Shdr sh64; +#endif /* __LIBELF64 */ + } u; + + /* + * Overflow in ehdr->e_shnum. + * Get real value from first SHDR. + */ + if (elf->e_size - off < entsz) { + seterr(ERROR_TRUNC_SHDR); + return 0; + } + if (elf->e_rawdata) { + src.d_buf = elf->e_rawdata + off; + } + else { + src.d_buf = elf->e_data + off; + } + dst.d_buf = &u; + dst.d_size = sizeof(u); + if (!_elf_xlatetom(elf, &dst, &src)) { + return 0; + } + elf_assert(dst.d_size == _msize(elf->e_class, EV_CURRENT, ELF_T_SHDR)); + elf_assert(dst.d_type == ELF_T_SHDR); + if (elf->e_class == ELFCLASS32) { + num = u.sh32.sh_size; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + num = u.sh64.sh_size; + /* + * Check for overflow on 32-bit systems + */ + if (overflow(num, u.sh64.sh_size, Elf64_Xword)) { + seterr(ERROR_OUTSIDE); + return 0; + } + } +#endif /* __LIBELF64 */ + } + + if ((elf->e_size - off) / entsz < num) { + seterr(ERROR_TRUNC_SHDR); + return 0; + } + + if (!(head = (struct tmp*)malloc(num * sizeof(struct tmp)))) { + seterr(ERROR_MEM_SCN); + return 0; + } + for (scn = NULL, i = num; i-- > 0; ) { + head[i].scn = _elf_scn_init; + head[i].data = _elf_data_init; + head[i].scn.s_link = scn; + if (!scn) { + elf->e_scn_n = &head[i].scn; + } + scn = &head[i].scn; + sd = &head[i].data; + + if (elf->e_rawdata) { + src.d_buf = elf->e_rawdata + off + i * entsz; + } + else { + src.d_buf = elf->e_data + off + i * entsz; + } + dst.d_buf = &scn->s_uhdr; + dst.d_size = sizeof(scn->s_uhdr); + if (!_elf_xlatetom(elf, &dst, &src)) { + elf->e_scn_n = NULL; + free(head); + return 0; + } + elf_assert(dst.d_size == _msize(elf->e_class, EV_CURRENT, ELF_T_SHDR)); + elf_assert(dst.d_type == ELF_T_SHDR); + + scn->s_elf = elf; + scn->s_index = i; + scn->s_data_1 = sd; + scn->s_data_n = sd; + + sd->sd_scn = scn; + + if (elf->e_class == ELFCLASS32) { + Elf32_Shdr *shdr = &scn->s_shdr32; + + scn->s_type = shdr->sh_type; + scn->s_size = shdr->sh_size; + scn->s_offset = shdr->sh_offset; + sd->sd_data.d_align = shdr->sh_addralign; + sd->sd_data.d_type = _elf_scn_type(scn->s_type); + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + Elf64_Shdr *shdr = &scn->s_shdr64; + + scn->s_type = shdr->sh_type; + scn->s_size = shdr->sh_size; + scn->s_offset = shdr->sh_offset; + sd->sd_data.d_align = shdr->sh_addralign; + /* + * Check for overflow on 32-bit systems + */ + if (overflow(scn->s_size, shdr->sh_size, Elf64_Xword) + || overflow(scn->s_offset, shdr->sh_offset, Elf64_Off) + || overflow(sd->sd_data.d_align, shdr->sh_addralign, Elf64_Xword)) { + seterr(ERROR_OUTSIDE); + return 0; + } + sd->sd_data.d_type = _elf_scn_type(scn->s_type); + /* + * QUIRKS MODE: + * + * Some 64-bit architectures use 64-bit entries in the + * .hash section. This violates the ELF standard, and + * should be fixed. It's mostly harmless as long as the + * binary and the machine running your program have the + * same byte order, but you're in trouble if they don't, + * and if the entry size is wrong. + * + * As a workaround, I let libelf guess the right size + * for the binary. This relies pretty much on the fact + * that the binary provides correct data in the section + * headers. If it doesn't, it's probably broken anyway. + * Therefore, libelf uses a standard conforming value + * when it's not absolutely sure. + */ + if (scn->s_type == SHT_HASH) { + int override = 0; + + /* + * sh_entsize must reflect the entry size + */ + if (shdr->sh_entsize == ELF64_FSZ_ADDR) { + override++; + } + /* + * sh_size must be a multiple of sh_entsize + */ + if (shdr->sh_size % ELF64_FSZ_ADDR == 0) { + override++; + } + /* + * There must be room for at least 2 entries + */ + if (shdr->sh_size >= 2 * ELF64_FSZ_ADDR) { + override++; + } + /* + * sh_addralign must be correctly set + */ + if (shdr->sh_addralign == ELF64_FSZ_ADDR) { + override++; + } + /* + * The section must be properly aligned + */ + if (shdr->sh_offset % ELF64_FSZ_ADDR == 0) { + override++; + } + /* XXX: also look at the data? */ + /* + * Make a conservative decision... + */ + if (override >= 5) { + sd->sd_data.d_type = ELF_T_ADDR; + } + } + /* + * END QUIRKS MODE. + */ + } +#endif /* __LIBELF64 */ + /* we already had this + else { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + */ + + sd->sd_data.d_size = scn->s_size; + sd->sd_data.d_version = _elf_version; + } + elf_assert(scn == &head[0].scn); + elf->e_scn_1 = &head[0].scn; + head[0].scn.s_freeme = 1; + } + return 1; +} + +static int +_elf_cook_file(Elf *elf) { + elf->e_ehdr = _elf_item(NULL, elf, ELF_T_EHDR, 0); + if (!elf->e_ehdr) { + return 0; + } + /* + * Note: _elf_cook_phdr may require the first section header! + */ + if (!_elf_cook_shdr(elf)) { + return 0; + } + if (!_elf_cook_phdr(elf)) { + return 0; + } + return 1; +} + +int +_elf_cook(Elf *elf) { + elf_assert(_elf_scn_init.s_magic == SCN_MAGIC); + elf_assert(_elf_data_init.sd_magic == DATA_MAGIC); + elf_assert(elf); + elf_assert(elf->e_magic == ELF_MAGIC); + elf_assert(elf->e_kind == ELF_K_ELF); + elf_assert(!elf->e_ehdr); + if (!valid_version(elf->e_version)) { + seterr(ERROR_UNKNOWN_VERSION); + } + else if (!valid_encoding(elf->e_encoding)) { + seterr(ERROR_UNKNOWN_ENCODING); + } + else if (valid_class(elf->e_class)) { + return _elf_cook_file(elf); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return 0; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/data.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/data.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,36 @@ +/* + * data.c - libelf internal variables. + * Copyright (C) 1995 - 1998, 2007 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: data.c,v 1.7 2007/09/07 12:07:59 michael Exp $"; +#endif /* lint */ + +unsigned _elf_version = EV_NONE; +int _elf_errno = 0; +int _elf_fill = 0; + +#if ENABLE_SANITY_CHECKS +#define SANITY_CHECKS -1 +#else +#define SANITY_CHECKS 0 +#endif + +int _elf_sanity_checks = SANITY_CHECKS; diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/elf_repl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/elf_repl.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,992 @@ +/* + * elf_repl.h - public header file for systems that lack it. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* @(#) $Id: elf_repl.h,v 1.20 2006/07/07 22:16:15 michael Exp $ */ + +/* + * NEVER INCLUDE THIS FILE DIRECTLY - USE INSTEAD! + */ + +#ifndef _ELF_REPL_H +#define _ELF_REPL_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Scalar data types + */ +typedef __libelf_u32_t Elf32_Addr; +typedef __libelf_u16_t Elf32_Half; +typedef __libelf_u32_t Elf32_Off; +typedef __libelf_i32_t Elf32_Sword; +typedef __libelf_u32_t Elf32_Word; + +#define ELF32_FSZ_ADDR 4 +#define ELF32_FSZ_HALF 2 +#define ELF32_FSZ_OFF 4 +#define ELF32_FSZ_SWORD 4 +#define ELF32_FSZ_WORD 4 + +#if __LIBELF64 + +typedef __libelf_u64_t Elf64_Addr; +typedef __libelf_u16_t Elf64_Half; +typedef __libelf_u64_t Elf64_Off; +typedef __libelf_i32_t Elf64_Sword; +typedef __libelf_u32_t Elf64_Word; +typedef __libelf_i64_t Elf64_Sxword; +typedef __libelf_u64_t Elf64_Xword; + +#define ELF64_FSZ_ADDR 8 +#define ELF64_FSZ_HALF 2 +#define ELF64_FSZ_OFF 8 +#define ELF64_FSZ_SWORD 4 +#define ELF64_FSZ_WORD 4 +#define ELF64_FSZ_SXWORD 8 +#define ELF64_FSZ_XWORD 8 + +/* + * Blame Sun for this... + */ +typedef __libelf_u64_t Elf64_Lword; +typedef __libelf_u64_t Elf32_Lword; + +#endif /* __LIBELF64 */ + +/* + * ELF header + */ +#define EI_NIDENT 16 + +typedef struct { + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} Elf32_Ehdr; + +#if __LIBELF64 +typedef struct { + unsigned char e_ident[EI_NIDENT]; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; +} Elf64_Ehdr; +#endif /* __LIBELF64 */ + +/* + * e_ident + */ +#define EI_MAG0 0 +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_OSABI 7 +#define EI_ABIVERSION 8 +#define EI_PAD 9 + +#define ELFMAG0 0x7f +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +/* + * e_ident[EI_CLASS] + */ +#define ELFCLASSNONE 0 +#define ELFCLASS32 1 +#define ELFCLASS64 2 +#define ELFCLASSNUM 3 + +/* + * e_ident[EI_DATA] + */ +#define ELFDATANONE 0 +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 +#define ELFDATANUM 3 + +/* + * e_ident[EI_OSABI] + */ +#define ELFOSABI_NONE 0 /* No extensions or unspecified */ +#define ELFOSABI_SYSV ELFOSABI_NONE +#define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */ +#define ELFOSABI_NETBSD 2 /* NetBSD */ +#define ELFOSABI_LINUX 3 /* Linux */ +#define ELFOSABI_SOLARIS 6 /* Sun Solaris */ +#define ELFOSABI_AIX 7 /* AIX */ +#define ELFOSABI_IRIX 8 /* IRIX */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD */ +#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto */ +#define ELFOSABI_OPENBSD 12 /* Open BSD */ +#define ELFOSABI_OPENVMS 13 /* Open VMS */ +#define ELFOSABI_NSK 14 /* Hewlett-Packard Non-Stop Kernel */ +#define ELFOSABI_AROS 15 /* Amiga Research OS */ +/* these are probably obsolete: */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* standalone (embedded) application */ + + +/* + * e_type + */ +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 +#define ET_NUM 5 +#define ET_LOOS 0xfe00 +#define ET_HIOS 0xfeff +#define ET_LOPROC 0xff00 +#define ET_HIPROC 0xffff + +/* + * e_machine + */ +#define EM_NONE 0 /* No machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola 68000 */ +#define EM_88K 5 /* Motorola 88000 */ +#define EM_486 6 /* Intel i486 (DO NOT USE THIS ONE) */ +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS I Architecture */ +#define EM_S370 9 /* IBM System/370 Processor */ +#define EM_MIPS_RS3_LE 10 /* MIPS RS3000 Little-endian */ +#define EM_SPARC64 11 /* SPARC 64-bit */ +#define EM_PARISC 15 /* Hewlett-Packard PA-RISC */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* 64-bit PowerPC */ +#define EM_S390 22 /* IBM System/390 Processor */ +#define EM_V800 36 /* NEC V800 */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH-32 */ +#define EM_RCE 39 /* Motorola RCE */ +#define EM_ARM 40 /* Advanced RISC Machines ARM */ +#define EM_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC Version 9 */ +#define EM_TRICORE 44 /* Siemens TriCore embedded processor */ +#define EM_ARC 45 /* Argonaut RISC Core, Argonaut Technologies Inc. */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel IA-64 processor architecture */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola ColdFire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator */ +#define EM_PCP 55 /* Siemens PCP */ +#define EM_NCPU 56 /* Sony nCPU embedded RISC processor */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor */ +#define EM_STARCORE 58 /* Motorola Star*Core processor */ +#define EM_ME16 59 /* Toyota ME16 processor */ +#define EM_ST100 60 /* STMicroelectronics ST100 processor */ +#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ embedded processor family */ +#define EM_X86_64 62 /* AMD x86-64 architecture */ +#define EM_AMD64 EM_X86_64 +#define EM_PDSP 63 /* Sony DSP Processor */ +#define EM_FX66 66 /* Siemens FX66 microcontroller */ +#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 bit microcontroller */ +#define EM_ST7 68 /* STMicroelectronics ST7 8-bit microcontroller */ +#define EM_68HC16 69 /* Motorola MC68HC16 Microcontroller */ +#define EM_68HC11 70 /* Motorola MC68HC11 Microcontroller */ +#define EM_68HC08 71 /* Motorola MC68HC08 Microcontroller */ +#define EM_68HC05 72 /* Motorola MC68HC05 Microcontroller */ +#define EM_SVX 73 /* Silicon Graphics SVx */ +#define EM_ST19 74 /* STMicroelectronics ST19 8-bit microcontroller */ +#define EM_VAX 75 /* Digital VAX */ +#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ +#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ +#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ +#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ +#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ +#define EM_HUANY 81 /* Harvard University machine-independent object files */ +#define EM_PRISM 82 /* SiTera Prism */ +#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ +#define EM_FR30 84 /* Fujitsu FR30 */ +#define EM_D10V 85 /* Mitsubishi D10V */ +#define EM_D30V 86 /* Mitsubishi D30V */ +#define EM_V850 87 /* NEC v850 */ +#define EM_M32R 88 /* Mitsubishi M32R */ +#define EM_MN10300 89 /* Matsushita MN10300 */ +#define EM_MN10200 90 /* Matsushita MN10200 */ +#define EM_PJ 91 /* picoJava */ +#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ +#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ +#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ +#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor */ +#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose Processor */ +#define EM_NS32K 97 /* National Semiconductor 32000 series */ +#define EM_TPC 98 /* Tenor Network TPC processor */ +#define EM_SNP1K 99 /* Trebia SNP 1000 processor */ +#define EM_ST200 100 /* STMicroelectronics (www.st.com) ST200 microcontroller */ +#define EM_IP2K 101 /* Ubicom IP2xxx microcontroller family */ +#define EM_MAX 102 /* MAX Processor */ +#define EM_CR 103 /* National Semiconductor CompactRISC microprocessor */ +#define EM_F2MC16 104 /* Fujitsu F2MC16 */ +#define EM_MSP430 105 /* Texas Instruments embedded microcontroller msp430 */ +#define EM_BLACKFIN 106 /* Analog Devices Blackfin (DSP) processor */ +#define EM_SE_C33 107 /* S1C33 Family of Seiko Epson processors */ +#define EM_SEP 108 /* Sharp embedded microprocessor */ +#define EM_ARCA 109 /* Arca RISC Microprocessor */ +#define EM_UNICORE 110 /* Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University */ +#define EM_NUM 111 + +/* + * e_ident[EI_VERSION], e_version + */ +#define EV_NONE 0 +#define EV_CURRENT 1 +#define EV_NUM 2 + +/* + * Section header + */ +typedef struct { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; +} Elf32_Shdr; + +#if __LIBELF64 +typedef struct { + Elf64_Word sh_name; + Elf64_Word sh_type; + Elf64_Xword sh_flags; + Elf64_Addr sh_addr; + Elf64_Off sh_offset; + Elf64_Xword sh_size; + Elf64_Word sh_link; + Elf64_Word sh_info; + Elf64_Xword sh_addralign; + Elf64_Xword sh_entsize; +} Elf64_Shdr; +#endif /* __LIBELF64 */ + +/* + * Special section indices + */ +#define SHN_UNDEF 0 +#define SHN_LORESERVE 0xff00 +#define SHN_LOPROC 0xff00 +#define SHN_HIPROC 0xff1f +#define SHN_LOOS 0xff20 +#define SHN_HIOS 0xff3f +#define SHN_ABS 0xfff1 +#define SHN_COMMON 0xfff2 +#define SHN_XINDEX 0xffff +#define SHN_HIRESERVE 0xffff + +/* + * sh_type + */ +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 +#define SHT_INIT_ARRAY 14 +#define SHT_FINI_ARRAY 15 +#define SHT_PREINIT_ARRAY 16 +#define SHT_GROUP 17 +#define SHT_SYMTAB_SHNDX 18 +#define SHT_NUM 19 +#define SHT_LOOS 0x60000000 +#define SHT_HIOS 0x6fffffff +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7fffffff +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xffffffff + +/* + * Solaris extensions + */ +#define SHT_LOSUNW 0x6ffffff4 +#define SHT_SUNW_dof 0x6ffffff4 +#define SHT_SUNW_cap 0x6ffffff5 +#define SHT_SUNW_SIGNATURE 0x6ffffff6 +#define SHT_SUNW_ANNOTATE 0x6ffffff7 +#define SHT_SUNW_DEBUGSTR 0x6ffffff8 +#define SHT_SUNW_DEBUG 0x6ffffff9 +#define SHT_SUNW_move 0x6ffffffa +#define SHT_SUNW_COMDAT 0x6ffffffb +#define SHT_SUNW_syminfo 0x6ffffffc +#define SHT_SUNW_verdef 0x6ffffffd +#define SHT_SUNW_verneed 0x6ffffffe +#define SHT_SUNW_versym 0x6fffffff +#define SHT_HISUNW 0x6fffffff + +#define SHT_SPARC_GOTDATA 0x70000000 +#define SHT_AMD64_UNWIND 0x70000001 + +/* + * GNU extensions + */ +#define SHT_GNU_verdef 0x6ffffffd +#define SHT_GNU_verneed 0x6ffffffe +#define SHT_GNU_versym 0x6fffffff + +/* + * sh_flags + */ +#define SHF_WRITE 0x1 +#define SHF_ALLOC 0x2 +#define SHF_EXECINSTR 0x4 +#define SHF_MERGE 0x10 +#define SHF_STRINGS 0x20 +#define SHF_INFO_LINK 0x40 +#define SHF_LINK_ORDER 0x80 +#define SHF_OS_NONCONFORMING 0x100 +#define SHF_GROUP 0x200 +#define SHF_TLS 0x400 +#define SHF_MASKOS 0x0ff00000 +#define SHF_MASKPROC 0xf0000000 + +/* + * Solaris extensions + */ +#define SHF_AMD64_LARGE 0x10000000 +#define SHF_ORDERED 0x40000000 +#define SHF_EXCLUDE 0x80000000 + +/* + * Section group flags + */ +#define GRP_COMDAT 0x1 +#define GRP_MASKOS 0x0ff00000 +#define GRP_MASKPROC 0xf0000000 + +/* + * Symbol table + */ +typedef struct { + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; +} Elf32_Sym; + +#if __LIBELF64 +typedef struct { + Elf64_Word st_name; + unsigned char st_info; + unsigned char st_other; + Elf64_Half st_shndx; + Elf64_Addr st_value; + Elf64_Xword st_size; +} Elf64_Sym; +#endif /* __LIBELF64 */ + +/* + * Special symbol indices + */ +#define STN_UNDEF 0 + +/* + * Macros for manipulating st_info + */ +#define ELF32_ST_BIND(i) ((i)>>4) +#define ELF32_ST_TYPE(i) ((i)&0xf) +#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf)) + +#if __LIBELF64 +#define ELF64_ST_BIND(i) ((i)>>4) +#define ELF64_ST_TYPE(i) ((i)&0xf) +#define ELF64_ST_INFO(b,t) (((b)<<4)+((t)&0xf)) +#endif /* __LIBELF64 */ + +/* + * Symbol binding + */ +#define STB_LOCAL 0 +#define STB_GLOBAL 1 +#define STB_WEAK 2 +#define STB_NUM 3 +#define STB_LOOS 10 +#define STB_HIOS 12 +#define STB_LOPROC 13 +#define STB_HIPROC 15 + +/* + * Symbol types + */ +#define STT_NOTYPE 0 +#define STT_OBJECT 1 +#define STT_FUNC 2 +#define STT_SECTION 3 +#define STT_FILE 4 +#define STT_COMMON 5 +#define STT_TLS 6 +#define STT_NUM 7 +#define STT_LOOS 10 +#define STT_HIOS 12 +#define STT_LOPROC 13 +#define STT_HIPROC 15 + +/* + * Macros for manipulating st_other + */ +#define ELF32_ST_VISIBILITY(o) ((o)&0x3) +#if __LIBELF64 +#define ELF64_ST_VISIBILITY(o) ((o)&0x3) +#endif /* __LIBELF64 */ + +/* + * Symbol visibility + */ +#define STV_DEFAULT 0 +#define STV_INTERNAL 1 +#define STV_HIDDEN 2 +#define STV_PROTECTED 3 + +/* + * Relocation + */ +typedef struct { + Elf32_Addr r_offset; + Elf32_Word r_info; +} Elf32_Rel; + +typedef struct { + Elf32_Addr r_offset; + Elf32_Word r_info; + Elf32_Sword r_addend; +} Elf32_Rela; + +#if __LIBELF64 +typedef struct { + Elf64_Addr r_offset; + Elf64_Xword r_info; +} Elf64_Rel; + +typedef struct { + Elf64_Addr r_offset; + Elf64_Xword r_info; + Elf64_Sxword r_addend; +} Elf64_Rela; +#endif /* __LIBELF64 */ + +/* + * Macros for manipulating r_info + */ +#define ELF32_R_SYM(i) ((i)>>8) +#define ELF32_R_TYPE(i) ((unsigned char)(i)) +#define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t)) + +#if __LIBELF64 +#define ELF64_R_SYM(i) ((Elf64_Xword)(i)>>32) +#define ELF64_R_TYPE(i) ((i)&0xffffffffL) +#define ELF64_R_INFO(s,t) (((Elf64_Xword)(s)<<32)+((t)&0xffffffffL)) +#endif /* __LIBELF64 */ + +/* + * Note entry header + */ +typedef struct { + Elf32_Word n_namesz; /* name size */ + Elf32_Word n_descsz; /* descriptor size */ + Elf32_Word n_type; /* descriptor type */ +} Elf32_Nhdr; + +#if __LIBELF64 +/* Solaris and GNU use this layout. Be compatible. */ +/* XXX: Latest ELF specs say it's 64-bit!!! */ +typedef struct { + Elf64_Word n_namesz; /* name size */ + Elf64_Word n_descsz; /* descriptor size */ + Elf64_Word n_type; /* descriptor type */ +} Elf64_Nhdr; +#endif /* __LIBELF64 */ + +/* + * Well-known descriptor types for ET_CORE files + */ +#define NT_PRSTATUS 1 +#define NT_PRFPREG 2 +#define NT_PRPSINFO 3 + +/* + * Program header + */ +typedef struct { + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +} Elf32_Phdr; + +#if __LIBELF64 +typedef struct { + Elf64_Word p_type; + Elf64_Word p_flags; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Addr p_paddr; + Elf64_Xword p_filesz; + Elf64_Xword p_memsz; + Elf64_Xword p_align; +} Elf64_Phdr; +#endif /* __LIBELF64 */ + +/* + * Special numbers + */ +#define PN_XNUM 0xffff + +/* + * p_type + */ +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_TLS 7 +#define PT_NUM 8 +#define PT_LOOS 0x60000000 +#define PT_HIOS 0x6fffffff +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff + +/* + * Solaris extensions + */ + +#define PT_SUNW_UNWIND 0x6464e550 +#define PT_LOSUNW 0x6ffffffa +#define PT_SUNWBSS 0x6ffffffa +#define PT_SUNWSTACK 0x6ffffffb +#define PT_SUNWDTRACE 0x6ffffffc +#define PT_SUNWCAP 0x6ffffffd +#define PT_HISUNW 0x6fffffff + +/* + * p_flags + */ +#define PF_X 0x1 +#define PF_W 0x2 +#define PF_R 0x4 +#define PF_MASKOS 0x0ff00000 +#define PF_MASKPROC 0xf0000000 + +/* + * Dynamic structure + */ +typedef struct { + Elf32_Sword d_tag; + union { + Elf32_Word d_val; + Elf32_Addr d_ptr; + } d_un; +} Elf32_Dyn; + +#if __LIBELF64 +typedef struct { + Elf64_Sxword d_tag; + union { + Elf64_Xword d_val; + Elf64_Addr d_ptr; + } d_un; +} Elf64_Dyn; +#endif /* __LIBELF64 */ + +/* + * Dynamic array tags + */ + /* d_un exec shared */ +#define DT_NULL 0 /* ign. mand. mand. */ +#define DT_NEEDED 1 /* d_val opt. opt. */ +#define DT_PLTRELSZ 2 /* d_val opt. opt. */ +#define DT_PLTGOT 3 /* d_ptr opt. opt. */ +#define DT_HASH 4 /* d_ptr mand. mand. */ +#define DT_STRTAB 5 /* d_ptr mand. mand. */ +#define DT_SYMTAB 6 /* d_ptr mand. mand. */ +#define DT_RELA 7 /* d_ptr mand. opt. */ +#define DT_RELASZ 8 /* d_val mand. opt. */ +#define DT_RELAENT 9 /* d_val mand. opt. */ +#define DT_STRSZ 10 /* d_val mand. mand. */ +#define DT_SYMENT 11 /* d_val mand. mand. */ +#define DT_INIT 12 /* d_ptr opt. opt. */ +#define DT_FINI 13 /* d_ptr opt. opt. */ +#define DT_SONAME 14 /* d_val ign. opt. */ +#define DT_RPATH 15 /* d_val opt. ign. */ +#define DT_SYMBOLIC 16 /* ign. ign. opt. */ +#define DT_REL 17 /* d_ptr mand. opt. */ +#define DT_RELSZ 18 /* d_val mand. opt. */ +#define DT_RELENT 19 /* d_val mand. opt. */ +#define DT_PLTREL 20 /* d_val opt. opt. */ +#define DT_DEBUG 21 /* d_ptr opt. ign. */ +#define DT_TEXTREL 22 /* ign. opt. opt. */ +#define DT_JMPREL 23 /* d_ptr opt. opt. */ +#define DT_BIND_NOW 24 /* ign. opt. opt. */ +#define DT_INIT_ARRAY 25 /* d_ptr opt. opt. */ +#define DT_FINI_ARRAY 26 /* d_ptr opt. opt. */ +#define DT_INIT_ARRAYSZ 27 /* d_val opt. opt. */ +#define DT_FINI_ARRAYSZ 28 /* d_val opt. opt. */ +#define DT_RUNPATH 29 /* d_val opt. opt. */ +#define DT_FLAGS 30 /* d_val opt. opt. */ +#define DT_ENCODING 32 /* odd/even encoding rule starts here */ +#define DT_PREINIT_ARRAY 32 /* d_ptr opt. ign. */ +#define DT_PREINIT_ARRAYSZ 33 /* d_val opt. ign. */ +#define DT_NUM 34 +#define DT_LOOS 0x6000000D +#define DT_HIOS 0x6ffff000 +#define DT_LOPROC 0x70000000 +#define DT_HIPROC 0x7fffffff + +/* + * DT_FLAGS values + */ +#define DF_ORIGIN 0x1 +#define DF_SYMBOLIC 0x2 +#define DF_TEXTREL 0x4 +#define DF_BIND_NOW 0x8 +#define DF_STATIC_TLS 0x10 + +/* + * Solaris extensions + */ +#define DT_VALRNGLO 0x6ffffd00 +#define DT_CHECKSUM 0x6ffffdf8 +#define DT_PLTPADSZ 0x6ffffdf9 +#define DT_MOVEENT 0x6ffffdfa +#define DT_MOVESZ 0x6ffffdfb +#define DT_FEATURE_1 0x6ffffdfc +#define DT_POSFLAG_1 0x6ffffdfd +#define DT_SYMINSZ 0x6ffffdfe +#define DT_SYMINENT 0x6ffffdff +#define DT_VALRNGHI 0x6ffffdff + +#define DT_ADDRRNGLO 0x6ffffe00 +#define DT_CONFIG 0x6ffffefa +#define DT_DEPAUDIT 0x6ffffefb +#define DT_AUDIT 0x6ffffefc +#define DT_PLTPAD 0x6ffffefd +#define DT_MOVETAB 0x6ffffefe +#define DT_SYMINFO 0x6ffffeff +#define DT_ADDRRNGHI 0x6ffffeff + +#define DT_RELACOUNT 0x6ffffff9 +#define DT_RELCOUNT 0x6ffffffa +#define DT_FLAGS_1 0x6ffffffb +#define DT_VERDEF 0x6ffffffc +#define DT_VERDEFNUM 0x6ffffffd +#define DT_VERNEED 0x6ffffffe +#define DT_VERNEEDNUM 0x6fffffff + +#define DT_AUXILIARY 0x7ffffffd +#define DT_USED 0x7ffffffe +#define DT_FILTER 0x7fffffff + +/* + * GNU extensions + */ +#define DT_VERSYM 0x6ffffff0 + +/* + * DT_FEATURE_1 values + */ +#define DTF_1_PARINIT 0x1 +#define DTF_1_CONFEXP 0x2 + +/* + * DT_POSFLAG_1 values + */ +#define DF_P1_LAZYLOAD 0x1 +#define DF_P1_GROUPPERM 0x2 + +/* + * DT_FLAGS_1 values + */ +#define DF_1_NOW 0x00000001 +#define DF_1_GLOBAL 0x00000002 +#define DF_1_GROUP 0x00000004 +#define DF_1_NODELETE 0x00000008 +#define DF_1_LOADFLTR 0x00000010 +#define DF_1_INITFIRST 0x00000020 +#define DF_1_NOOPEN 0x00000040 +#define DF_1_ORIGIN 0x00000080 +#define DF_1_DIRECT 0x00000100 +#define DF_1_TRANS 0x00000200 +#define DF_1_INTERPOSE 0x00000400 +#define DF_1_NODEFLIB 0x00000800 +#define DF_1_NODUMP 0x00001000 +#define DF_1_CONFALT 0x00002000 +#define DF_1_ENDFILTEE 0x00004000 +#define DF_1_DISPRELDNE 0x00008000 +#define DF_1_DISPRELPND 0x00010000 + +/* + * Syminfo structure + */ +typedef struct { + Elf32_Half si_boundto; + Elf32_Half si_flags; +} Elf32_Syminfo; + +#if __LIBELF64 +typedef struct { + Elf64_Half si_boundto; + Elf64_Half si_flags; +} Elf64_Syminfo; +#endif /* __LIBELF64 */ + +/* + * Syminfo version (stored in unused first entry) + */ +#define SYMINFO_NONE 0 +#define SYMINFO_CURRENT 1 +#define SYMINFO_NUM 2 + +/* + * si_boundto special values + */ +#define SYMINFO_BT_LOWRESERVE 0xff00 +#define SYMINFO_BT_PARENT 0xfffe /* bound to parent */ +#define SYMINFO_BT_SELF 0xffff /* bound to self */ + +/* + * si_flags + */ +#define SYMINFO_FLG_DIRECT 0x01 /* bound to an object */ +#define SYMINFO_FLG_PASSTHRU 0x02 /* pass-thru symbol */ +#define SYMINFO_FLG_COPY 0x04 /* result of a copy relocation */ +#define SYMINFO_FLG_LAZYLOAD 0x08 /* bound to lazy-loaded object */ + +/* + * Version definitions + */ +typedef struct { + Elf32_Half vd_version; + Elf32_Half vd_flags; + Elf32_Half vd_ndx; + Elf32_Half vd_cnt; + Elf32_Word vd_hash; + Elf32_Word vd_aux; + Elf32_Word vd_next; +} Elf32_Verdef; + +typedef struct { + Elf32_Word vda_name; + Elf32_Word vda_next; +} Elf32_Verdaux; + +typedef struct { + Elf32_Half vn_version; + Elf32_Half vn_cnt; + Elf32_Word vn_file; + Elf32_Word vn_aux; + Elf32_Word vn_next; +} Elf32_Verneed; + +typedef struct { + Elf32_Word vna_hash; + Elf32_Half vna_flags; + Elf32_Half vna_other; + Elf32_Word vna_name; + Elf32_Word vna_next; +} Elf32_Vernaux; + +typedef Elf32_Half Elf32_Versym; + +#if __LIBELF64 + +typedef struct { + Elf64_Half vd_version; + Elf64_Half vd_flags; + Elf64_Half vd_ndx; + Elf64_Half vd_cnt; + Elf64_Word vd_hash; + Elf64_Word vd_aux; + Elf64_Word vd_next; +} Elf64_Verdef; + +typedef struct { + Elf64_Word vda_name; + Elf64_Word vda_next; +} Elf64_Verdaux; + +typedef struct { + Elf64_Half vn_version; + Elf64_Half vn_cnt; + Elf64_Word vn_file; + Elf64_Word vn_aux; + Elf64_Word vn_next; +} Elf64_Verneed; + +typedef struct { + Elf64_Word vna_hash; + Elf64_Half vna_flags; + Elf64_Half vna_other; + Elf64_Word vna_name; + Elf64_Word vna_next; +} Elf64_Vernaux; + +typedef Elf64_Half Elf64_Versym; + +#endif /* __LIBELF64 */ + +/* + * vd_version + */ +#define VER_DEF_NONE 0 +#define VER_DEF_CURRENT 1 +#define VER_DEF_NUM 2 + +/* + * vn_version + */ +#define VER_NEED_NONE 0 +#define VER_NEED_CURRENT 1 +#define VER_NEED_NUM 2 + +/* + * vd_flags / vna_flags + */ +#define VER_FLG_BASE 0x1 /* vd_flags only */ +#define VER_FLG_WEAK 0x2 + +/* + * Elf*_Versym special values + */ +#define VER_NDX_LOCAL 0 +#define VER_NDX_GLOBAL 1 + +/* + * Solaris extensions + */ + +/* + * Move section + */ +#if __LIBELF64 + +typedef struct { + Elf32_Lword m_value; + Elf32_Word m_info; + Elf32_Word m_poffset; + Elf32_Half m_repeat; + Elf32_Half m_stride; +} Elf32_Move; + +typedef struct { + Elf64_Lword m_value; + Elf64_Xword m_info; + Elf64_Xword m_poffset; + Elf64_Half m_repeat; + Elf64_Half m_stride; +} Elf64_Move; + +#define ELF32_M_SYM(info) ((info)>>8) +#define ELF32_M_SIZE(info) ((unsigned char)(info)) +#define ELF32_M_INFO(sym, sz) (((sym)<<8)+(unsigned char)(sz)) + +#define ELF64_M_SYM(info) ((Elf64_Xword)(info)>>8) +#define ELF64_M_SIZE(info) ((unsigned char)(info)) +#define ELF64_M_INFO(sym, sz) (((Elf64_Xword)(sym)<<8)+(unsigned char)(sz)) + +#endif /* __LIBELF64 */ + +/* + * Capabilities + */ + +typedef struct { + Elf32_Word c_tag; + union { + Elf32_Word c_val; + Elf32_Addr c_ptr; + } c_un; +} Elf32_Cap; + +typedef struct { + Elf64_Xword c_tag; + union { + Elf64_Xword c_val; + Elf64_Addr c_ptr; + } c_un; +} Elf64_Cap; + +#define CA_SUNW_NULL 0 /* c_un ignored */ +#define CA_SUNW_HW_1 1 /* c_un.c_val */ +#define CA_SUNW_SF_1 2 /* c_un.c_val */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ELF_REPL_H */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/end.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/end.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,118 @@ +/* + * end.c - implementation of the elf_end(3) function. + * Copyright (C) 1995 - 2004 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: end.c,v 1.11 2005/05/21 15:39:21 michael Exp $"; +#endif /* lint */ + +#if HAVE_MMAP +#include +#endif /* HAVE_MMAP */ + +static void +_elf_free(void *ptr) { + if (ptr) { + free(ptr); + } +} + +static void +_elf_free_scns(Elf *elf, Elf_Scn *scn) { + Scn_Data *sd, *tmp; + Elf_Scn *freescn; + + for (freescn = NULL; scn; scn = scn->s_link) { + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf == elf); + for (sd = scn->s_data_1; sd; sd = tmp) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + tmp = sd->sd_link; + if (sd->sd_free_data) { + _elf_free(sd->sd_memdata); + } + if (sd->sd_freeme) { + free(sd); + } + } + if ((sd = scn->s_rawdata)) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + if (sd->sd_free_data) { + _elf_free(sd->sd_memdata); + } + if (sd->sd_freeme) { + free(sd); + } + } + if (scn->s_freeme) { + _elf_free(freescn); + freescn = scn; + } + } + _elf_free(freescn); +} + +int +elf_end(Elf *elf) { + Elf **siblings; + + if (!elf) { + return 0; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (--elf->e_count) { + return elf->e_count; + } + if (elf->e_parent) { + elf_assert(elf->e_parent->e_magic == ELF_MAGIC); + elf_assert(elf->e_parent->e_kind == ELF_K_AR); + siblings = &elf->e_parent->e_members; + while (*siblings) { + if (*siblings == elf) { + *siblings = elf->e_link; + break; + } + siblings = &(*siblings)->e_link; + } + elf_end(elf->e_parent); + _elf_free(elf->e_arhdr); + } +#if HAVE_MMAP + else if (elf->e_unmap_data) { + munmap(elf->e_data, elf->e_size); + } +#endif /* HAVE_MMAP */ + else if (!elf->e_memory) { + _elf_free(elf->e_data); + } + _elf_free_scns(elf, elf->e_scn_1); + if (elf->e_rawdata != elf->e_data) { + _elf_free(elf->e_rawdata); + } + if (elf->e_free_syms) { + _elf_free(elf->e_symtab); + } + _elf_free(elf->e_ehdr); + _elf_free(elf->e_phdr); + free(elf); + return 0; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/errmsg.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/errmsg.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,77 @@ +/* + * errmsg.c - implementation of the elf_errmsg(3) function. + * Copyright (C) 1995 - 1999, 2004 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: errmsg.c,v 1.10 2005/05/21 15:39:21 michael Exp $"; +#endif /* lint */ + +#if HAVE_DGETTEXT +# undef HAVE_CATGETS +# include +#else /* HAVE_DGETTEXT */ +# define dgettext(dom, str) str +#endif /* HAVE_DGETTEXT */ + +#if HAVE_CATGETS +# include +static nl_catd _libelf_cat = (nl_catd)0; +#endif /* HAVE_CATGETS */ + +#if HAVE_DGETTEXT || HAVE_CATGETS +static const char domain[] = "libelf"; +#endif /* HAVE_DGETTEXT || HAVE_CATGETS */ + +#if PIC +static const char *_messages[] = { +#else /* PIC */ +static const char *const _messages[] = { +#endif /* PIC */ +#define __err__(a,b) b, +#include /* include string tables from errors.h */ +#undef __err__ +}; + +const char* +elf_errmsg(int err) { + if (err == 0) { + err = _elf_errno; + if (err == 0) { + return NULL; + } + } + else if (err == -1) { + err = _elf_errno; + } + + if (err < 0 || err >= ERROR_NUM || _messages[err] == NULL) { + err = ERROR_UNKNOWN; + } + +#if HAVE_CATGETS + if (_libelf_cat == (nl_catd)0) { + _libelf_cat = catopen(domain, 0); + } + if (_libelf_cat != (nl_catd)-1) { + return catgets(_libelf_cat, 1, err + 1, _messages[err]); + } +#endif /* HAVE_CATGETS */ + return dgettext(domain, _messages[err]); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/errno.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/errno.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,32 @@ +/* +errno.c - implementation of the elf_errno(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: errno.c,v 1.6 2005/05/21 15:39:21 michael Exp $"; +#endif /* lint */ + +int +elf_errno(void) { + int tmp = _elf_errno; + + _elf_errno = 0; + return tmp; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/errors.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/errors.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,100 @@ +/* + * errors.h - exhaustive list of all error codes and messages for libelf. + * Copyright (C) 1995 - 2003, 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* @(#) $Id: errors.h,v 1.17 2006/04/21 17:17:46 michael Exp $ */ + +/* dummy for xgettext */ +#define _(str) str + +__err__(ERROR_OK, _("no error")) +__err__(ERROR_UNKNOWN, _("unknown error")) +__err__(ERROR_INTERNAL, _("Internal error: unknown reason")) +__err__(ERROR_UNIMPLEMENTED, _("Internal error: not implemented")) +__err__(ERROR_WRONLY, _("Request error: cntl(ELF_C_FDREAD) on write-only file")) +__err__(ERROR_INVALID_CMD, _("Request error: invalid ELF_C_* argument")) +__err__(ERROR_FDDISABLED, _("Request error: file descriptor disabled")) +__err__(ERROR_NOTARCHIVE, _("Request error: not an archive")) +__err__(ERROR_BADOFF, _("Request error: offset out of range")) +__err__(ERROR_UNKNOWN_VERSION, _("Request error: unknown ELF version")) +__err__(ERROR_CMDMISMATCH, _("Request error: ELF_C_* argument does not match")) +__err__(ERROR_MEMBERWRITE, _("Request error: archive member begin() for writing")) +__err__(ERROR_FDMISMATCH, _("Request error: archive/member file descriptor mismatch")) +__err__(ERROR_NOTELF, _("Request error: not an ELF file")) +__err__(ERROR_CLASSMISMATCH, _("Request error: class file/memory mismatch")) +__err__(ERROR_UNKNOWN_TYPE, _("Request error: invalid ELF_T_* argument")) +__err__(ERROR_UNKNOWN_ENCODING, _("Request error: unknown data encoding")) +__err__(ERROR_DST2SMALL, _("Request error: destination buffer too small")) +__err__(ERROR_NULLBUF, _("Request error: d_buf is NULL")) +__err__(ERROR_UNKNOWN_CLASS, _("Request error: unknown ELF class")) +__err__(ERROR_ELFSCNMISMATCH, _("Request error: section does not belong to file")) +__err__(ERROR_NOSUCHSCN, _("Request error: no section at index")) +__err__(ERROR_NULLSCN, _("Request error: can't manipulate null section")) +__err__(ERROR_SCNDATAMISMATCH, _("Request error: data does not belong to section")) +__err__(ERROR_NOSTRTAB, _("Request error: no string table")) +__err__(ERROR_BADSTROFF, _("Request error: string table offset out of range")) +__err__(ERROR_RDONLY, _("Request error: update(ELF_C_WRITE) on read-only file")) +__err__(ERROR_IO_SEEK, _("I/O error: seek")) +__err__(ERROR_IO_2BIG, _("I/O error: file too big for memory")) +__err__(ERROR_IO_READ, _("I/O error: raw read")) +__err__(ERROR_IO_GETSIZE, _("I/O error: get file size")) +__err__(ERROR_IO_WRITE, _("I/O error: output write")) +__err__(ERROR_IO_TRUNC, _("I/O error: can't truncate output file")) +__err__(ERROR_VERSION_UNSET, _("Sequence error: must set ELF version first")) +__err__(ERROR_NOEHDR, _("Sequence error: must create ELF header first")) +__err__(ERROR_OUTSIDE, _("Format error: reference outside file")) +__err__(ERROR_TRUNC_ARHDR, _("Format error: archive header truncated")) +__err__(ERROR_ARFMAG, _("Format error: archive fmag")) +__err__(ERROR_ARHDR, _("Format error: archive header")) +__err__(ERROR_TRUNC_MEMBER, _("Format error: archive member truncated")) +__err__(ERROR_SIZE_ARSYMTAB, _("Format error: archive symbol table size")) +__err__(ERROR_ARSTRTAB, _("Format error: archive string table")) +__err__(ERROR_ARSPECIAL, _("Format error: archive special name unknown")) +__err__(ERROR_TRUNC_EHDR, _("Format error: ELF header truncated")) +__err__(ERROR_TRUNC_PHDR, _("Format error: program header table truncated")) +__err__(ERROR_TRUNC_SHDR, _("Format error: section header table truncated")) +__err__(ERROR_TRUNC_SCN, _("Format error: data region truncated")) +__err__(ERROR_ALIGN_PHDR, _("Format error: program header table alignment")) +__err__(ERROR_ALIGN_SHDR, _("Format error: section header table alignment")) +__err__(ERROR_VERDEF_FORMAT, _("Format error: bad parameter in Verdef record")) +__err__(ERROR_VERDEF_VERSION, _("Format error: unknown Verdef version")) +__err__(ERROR_VERNEED_FORMAT, _("Format error: bad parameter in Verneed record")) +__err__(ERROR_VERNEED_VERSION, _("Format error: unknown Verneed version")) +__err__(ERROR_EHDR_SHNUM, _("Format error: bad e_shnum value")) +__err__(ERROR_EHDR_SHENTSIZE, _("Format error: bad e_shentsize value")) +__err__(ERROR_EHDR_PHENTSIZE, _("Format error: bad e_phentsize value")) +__err__(ERROR_UNTERM, _("Format error: unterminated string in string table")) +__err__(ERROR_SCN2SMALL, _("Layout error: section size too small for data")) +__err__(ERROR_SCN_OVERLAP, _("Layout error: overlapping sections")) +__err__(ERROR_MEM_ELF, _("Memory error: elf descriptor")) +__err__(ERROR_MEM_ARSYMTAB, _("Memory error: archive symbol table")) +__err__(ERROR_MEM_ARHDR, _("Memory error: archive member header")) +__err__(ERROR_MEM_EHDR, _("Memory error: ELF header")) +__err__(ERROR_MEM_PHDR, _("Memory error: program header table")) +__err__(ERROR_MEM_SHDR, _("Memory error: section header table")) +__err__(ERROR_MEM_SCN, _("Memory error: section descriptor")) +__err__(ERROR_MEM_SCNDATA, _("Memory error: section data")) +__err__(ERROR_MEM_OUTBUF, _("Memory error: output file space")) +__err__(ERROR_MEM_TEMPORARY, _("Memory error: temporary buffer")) +__err__(ERROR_BADVALUE, _("GElf error: value out of range")) +__err__(ERROR_BADINDEX, _("GElf error: index out of range")) +__err__(ERROR_BADTYPE, _("GElf error: type mismatch")) +__err__(ERROR_MEM_SYM, _("GElf error: not enough memory for GElf_Sym")) +__err__(ERROR_MEM_DYN, _("GElf error: not enough memory for GElf_Dyn")) +__err__(ERROR_MEM_RELA, _("GElf error: not enough memory for GElf_Rela")) +__err__(ERROR_MEM_REL, _("GElf error: not enough memory for GElf_Rel")) diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/ext_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/ext_types.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,334 @@ +/* +ext_types.h - external representation of ELF data types. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* @(#) $Id: ext_types.h,v 1.8 2005/05/21 15:39:22 michael Exp $ */ + +#ifndef _EXT_TYPES_H +#define _EXT_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Scalar data types + */ +typedef unsigned char __ext_Elf32_Addr [ELF32_FSZ_ADDR]; +typedef unsigned char __ext_Elf32_Half [ELF32_FSZ_HALF]; +typedef unsigned char __ext_Elf32_Off [ELF32_FSZ_OFF]; +typedef unsigned char __ext_Elf32_Sword [ELF32_FSZ_SWORD]; +typedef unsigned char __ext_Elf32_Word [ELF32_FSZ_WORD]; + +#if __LIBELF64 + +typedef unsigned char __ext_Elf32_Lword [8]; + +typedef unsigned char __ext_Elf64_Addr [ELF64_FSZ_ADDR]; +typedef unsigned char __ext_Elf64_Half [ELF64_FSZ_HALF]; +typedef unsigned char __ext_Elf64_Off [ELF64_FSZ_OFF]; +typedef unsigned char __ext_Elf64_Sword [ELF64_FSZ_SWORD]; +typedef unsigned char __ext_Elf64_Word [ELF64_FSZ_WORD]; +typedef unsigned char __ext_Elf64_Sxword[ELF64_FSZ_SXWORD]; +typedef unsigned char __ext_Elf64_Xword [ELF64_FSZ_XWORD]; + +typedef unsigned char __ext_Elf64_Lword [8]; + +#endif /* __LIBELF64 */ + +/* + * ELF header + */ +typedef struct { + unsigned char e_ident[EI_NIDENT]; + __ext_Elf32_Half e_type; + __ext_Elf32_Half e_machine; + __ext_Elf32_Word e_version; + __ext_Elf32_Addr e_entry; + __ext_Elf32_Off e_phoff; + __ext_Elf32_Off e_shoff; + __ext_Elf32_Word e_flags; + __ext_Elf32_Half e_ehsize; + __ext_Elf32_Half e_phentsize; + __ext_Elf32_Half e_phnum; + __ext_Elf32_Half e_shentsize; + __ext_Elf32_Half e_shnum; + __ext_Elf32_Half e_shstrndx; +} __ext_Elf32_Ehdr; + +#if __LIBELF64 +typedef struct { + unsigned char e_ident[EI_NIDENT]; + __ext_Elf64_Half e_type; + __ext_Elf64_Half e_machine; + __ext_Elf64_Word e_version; + __ext_Elf64_Addr e_entry; + __ext_Elf64_Off e_phoff; + __ext_Elf64_Off e_shoff; + __ext_Elf64_Word e_flags; + __ext_Elf64_Half e_ehsize; + __ext_Elf64_Half e_phentsize; + __ext_Elf64_Half e_phnum; + __ext_Elf64_Half e_shentsize; + __ext_Elf64_Half e_shnum; + __ext_Elf64_Half e_shstrndx; +} __ext_Elf64_Ehdr; +#endif /* __LIBELF64 */ + +/* + * Section header + */ +typedef struct { + __ext_Elf32_Word sh_name; + __ext_Elf32_Word sh_type; + __ext_Elf32_Word sh_flags; + __ext_Elf32_Addr sh_addr; + __ext_Elf32_Off sh_offset; + __ext_Elf32_Word sh_size; + __ext_Elf32_Word sh_link; + __ext_Elf32_Word sh_info; + __ext_Elf32_Word sh_addralign; + __ext_Elf32_Word sh_entsize; +} __ext_Elf32_Shdr; + +#if __LIBELF64 +typedef struct { + __ext_Elf64_Word sh_name; + __ext_Elf64_Word sh_type; + __ext_Elf64_Xword sh_flags; + __ext_Elf64_Addr sh_addr; + __ext_Elf64_Off sh_offset; + __ext_Elf64_Xword sh_size; + __ext_Elf64_Word sh_link; + __ext_Elf64_Word sh_info; + __ext_Elf64_Xword sh_addralign; + __ext_Elf64_Xword sh_entsize; +} __ext_Elf64_Shdr; +#endif /* __LIBELF64 */ + +/* + * Symbol table + */ +typedef struct { + __ext_Elf32_Word st_name; + __ext_Elf32_Addr st_value; + __ext_Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + __ext_Elf32_Half st_shndx; +} __ext_Elf32_Sym; + +#if __LIBELF64 +typedef struct { + __ext_Elf64_Word st_name; + unsigned char st_info; + unsigned char st_other; + __ext_Elf64_Half st_shndx; + __ext_Elf64_Addr st_value; + __ext_Elf64_Xword st_size; +} __ext_Elf64_Sym; +#endif /* __LIBELF64 */ + +/* + * Relocation + */ +typedef struct { + __ext_Elf32_Addr r_offset; + __ext_Elf32_Word r_info; +} __ext_Elf32_Rel; + +typedef struct { + __ext_Elf32_Addr r_offset; + __ext_Elf32_Word r_info; + __ext_Elf32_Sword r_addend; +} __ext_Elf32_Rela; + +#if __LIBELF64 +typedef struct { + __ext_Elf64_Addr r_offset; +#if __LIBELF64_IRIX + __ext_Elf64_Word r_sym; + unsigned char r_ssym; + unsigned char r_type3; + unsigned char r_type2; + unsigned char r_type; +#else /* __LIBELF64_IRIX */ + __ext_Elf64_Xword r_info; +#endif /* __LIBELF64_IRIX */ +} __ext_Elf64_Rel; + +typedef struct { + __ext_Elf64_Addr r_offset; +#if __LIBELF64_IRIX + __ext_Elf64_Word r_sym; + unsigned char r_ssym; + unsigned char r_type3; + unsigned char r_type2; + unsigned char r_type; +#else /* __LIBELF64_IRIX */ + __ext_Elf64_Xword r_info; +#endif /* __LIBELF64_IRIX */ + __ext_Elf64_Sxword r_addend; +} __ext_Elf64_Rela; +#endif /* __LIBELF64 */ + +/* + * Program header + */ +typedef struct { + __ext_Elf32_Word p_type; + __ext_Elf32_Off p_offset; + __ext_Elf32_Addr p_vaddr; + __ext_Elf32_Addr p_paddr; + __ext_Elf32_Word p_filesz; + __ext_Elf32_Word p_memsz; + __ext_Elf32_Word p_flags; + __ext_Elf32_Word p_align; +} __ext_Elf32_Phdr; + +#if __LIBELF64 +typedef struct { + __ext_Elf64_Word p_type; + __ext_Elf64_Word p_flags; + __ext_Elf64_Off p_offset; + __ext_Elf64_Addr p_vaddr; + __ext_Elf64_Addr p_paddr; + __ext_Elf64_Xword p_filesz; + __ext_Elf64_Xword p_memsz; + __ext_Elf64_Xword p_align; +} __ext_Elf64_Phdr; +#endif /* __LIBELF64 */ + +/* + * Dynamic structure + */ +typedef struct { + __ext_Elf32_Sword d_tag; + union { + __ext_Elf32_Word d_val; + __ext_Elf32_Addr d_ptr; + } d_un; +} __ext_Elf32_Dyn; + +#if __LIBELF64 +typedef struct { + __ext_Elf64_Sxword d_tag; + union { + __ext_Elf64_Xword d_val; + __ext_Elf64_Addr d_ptr; + } d_un; +} __ext_Elf64_Dyn; +#endif /* __LIBELF64 */ + +/* + * Version definitions + */ +typedef struct { + __ext_Elf32_Half vd_version; + __ext_Elf32_Half vd_flags; + __ext_Elf32_Half vd_ndx; + __ext_Elf32_Half vd_cnt; + __ext_Elf32_Word vd_hash; + __ext_Elf32_Word vd_aux; + __ext_Elf32_Word vd_next; +} __ext_Elf32_Verdef; + +typedef struct { + __ext_Elf32_Word vda_name; + __ext_Elf32_Word vda_next; +} __ext_Elf32_Verdaux; + +typedef struct { + __ext_Elf32_Half vn_version; + __ext_Elf32_Half vn_cnt; + __ext_Elf32_Word vn_file; + __ext_Elf32_Word vn_aux; + __ext_Elf32_Word vn_next; +} __ext_Elf32_Verneed; + +typedef struct { + __ext_Elf32_Word vna_hash; + __ext_Elf32_Half vna_flags; + __ext_Elf32_Half vna_other; + __ext_Elf32_Word vna_name; + __ext_Elf32_Word vna_next; +} __ext_Elf32_Vernaux; + +#if __LIBELF64 + +typedef struct { + __ext_Elf64_Half vd_version; + __ext_Elf64_Half vd_flags; + __ext_Elf64_Half vd_ndx; + __ext_Elf64_Half vd_cnt; + __ext_Elf64_Word vd_hash; + __ext_Elf64_Word vd_aux; + __ext_Elf64_Word vd_next; +} __ext_Elf64_Verdef; + +typedef struct { + __ext_Elf64_Word vda_name; + __ext_Elf64_Word vda_next; +} __ext_Elf64_Verdaux; + +typedef struct { + __ext_Elf64_Half vn_version; + __ext_Elf64_Half vn_cnt; + __ext_Elf64_Word vn_file; + __ext_Elf64_Word vn_aux; + __ext_Elf64_Word vn_next; +} __ext_Elf64_Verneed; + +typedef struct { + __ext_Elf64_Word vna_hash; + __ext_Elf64_Half vna_flags; + __ext_Elf64_Half vna_other; + __ext_Elf64_Word vna_name; + __ext_Elf64_Word vna_next; +} __ext_Elf64_Vernaux; + +#endif /* __LIBELF64 */ + +/* + * Move section + */ +#if __LIBELF64 + +typedef struct { + __ext_Elf32_Lword m_value; + __ext_Elf32_Word m_info; + __ext_Elf32_Word m_poffset; + __ext_Elf32_Half m_repeat; + __ext_Elf32_Half m_stride; +} __ext_Elf32_Move; + +typedef struct { + __ext_Elf64_Lword m_value; + __ext_Elf64_Xword m_info; + __ext_Elf64_Xword m_poffset; + __ext_Elf64_Half m_repeat; + __ext_Elf64_Half m_stride; +} __ext_Elf64_Move; + +#endif /* __LIBELF64 */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _EXT_TYPES_H */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/fill.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/fill.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,29 @@ +/* +fill.c - implementation of the elf_fill(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: fill.c,v 1.6 2005/05/21 15:39:22 michael Exp $"; +#endif /* lint */ + +void +elf_fill(int fill) { + _elf_fill = fill; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/flag.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/flag.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,92 @@ +/* +flag.c - implementation of the elf_flag*(3) functions. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: flag.c,v 1.6 2005/05/21 15:39:22 michael Exp $"; +#endif /* lint */ + +static unsigned +_elf_flag(unsigned *f, Elf_Cmd cmd, unsigned flags) { + if (cmd == ELF_C_SET) { + return *f |= flags; + } + if (cmd == ELF_C_CLR) { + return *f &= ~flags; + } + seterr(ERROR_INVALID_CMD); + return 0; +} + +unsigned +elf_flagdata(Elf_Data *data, Elf_Cmd cmd, unsigned flags) { + Scn_Data *sd = (Scn_Data*)data; + + if (!sd) { + return 0; + } + elf_assert(sd->sd_magic == DATA_MAGIC); + return _elf_flag(&sd->sd_data_flags, cmd, flags); +} + +unsigned +elf_flagehdr(Elf *elf, Elf_Cmd cmd, unsigned flags) { + if (!elf) { + return 0; + } + elf_assert(elf->e_magic == ELF_MAGIC); + return _elf_flag(&elf->e_ehdr_flags, cmd, flags); +} + +unsigned +elf_flagelf(Elf *elf, Elf_Cmd cmd, unsigned flags) { + if (!elf) { + return 0; + } + elf_assert(elf->e_magic == ELF_MAGIC); + return _elf_flag(&elf->e_elf_flags, cmd, flags); +} + +unsigned +elf_flagphdr(Elf *elf, Elf_Cmd cmd, unsigned flags) { + if (!elf) { + return 0; + } + elf_assert(elf->e_magic == ELF_MAGIC); + return _elf_flag(&elf->e_phdr_flags, cmd, flags); +} + +unsigned +elf_flagscn(Elf_Scn *scn, Elf_Cmd cmd, unsigned flags) { + if (!scn) { + return 0; + } + elf_assert(scn->s_magic == SCN_MAGIC); + return _elf_flag(&scn->s_scn_flags, cmd, flags); +} + +unsigned +elf_flagshdr(Elf_Scn *scn, Elf_Cmd cmd, unsigned flags) { + if (!scn) { + return 0; + } + elf_assert(scn->s_magic == SCN_MAGIC); + return _elf_flag(&scn->s_shdr_flags, cmd, flags); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/gelf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/gelf.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,155 @@ +/* + * gelf.h - public header file for libelf. + * Copyright (C) 2000 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* @(#) $Id: gelf.h,v 1.15 2006/09/07 15:55:42 michael Exp $ */ + +#ifndef _GELF_H +#define _GELF_H + +#if __LIBELF_INTERNAL__ +#include +#else /* __LIBELF_INTERNAL__ */ +#include +#endif /* __LIBELF_INTERNAL__ */ + +#if __LIBELF_NEED_LINK_H +#include +#elif __LIBELF_NEED_SYS_LINK_H +#include +#endif /* __LIBELF_NEED_LINK_H */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef __P +# if (__STDC__ + 0) || defined(__cplusplus) || defined(_WIN32) +# define __P(args) args +# else /* __STDC__ || defined(__cplusplus) */ +# define __P(args) () +# endif /* __STDC__ || defined(__cplusplus) */ +#endif /* __P */ + +#if !__LIBELF64 + +#error "GElf is not supported on this system." + +#else /* __LIBELF64 */ + +typedef Elf64_Addr GElf_Addr; +typedef Elf64_Half GElf_Half; +typedef Elf64_Off GElf_Off; +typedef Elf64_Sword GElf_Sword; +typedef Elf64_Word GElf_Word; +typedef Elf64_Sxword GElf_Sxword; +typedef Elf64_Xword GElf_Xword; + +typedef Elf64_Ehdr GElf_Ehdr; +typedef Elf64_Phdr GElf_Phdr; +typedef Elf64_Shdr GElf_Shdr; +typedef Elf64_Dyn GElf_Dyn; +typedef Elf64_Rel GElf_Rel; +typedef Elf64_Rela GElf_Rela; +typedef Elf64_Sym GElf_Sym; + +/* + * Symbol versioning + */ +#if __LIBELF_SYMBOL_VERSIONS +typedef Elf64_Verdef GElf_Verdef; +typedef Elf64_Verneed GElf_Verneed; +typedef Elf64_Verdaux GElf_Verdaux; +typedef Elf64_Vernaux GElf_Vernaux; +#endif /* __LIBELF_SYMBOL_VERSIONS */ + +/* + * These types aren't implemented (yet) + * +typedef Elf64_Move GElf_Move; +typedef Elf64_Syminfo GElf_Syminfo; + */ + +/* + * Generic macros + */ +#define GELF_ST_BIND ELF64_ST_BIND +#define GELF_ST_TYPE ELF64_ST_TYPE +#define GELF_ST_INFO ELF64_ST_INFO + +#define GELF_R_TYPE ELF64_R_TYPE +#define GELF_R_SYM ELF64_R_SYM +#define GELF_R_INFO ELF64_R_INFO + +/* + * Function declarations + */ +extern int gelf_getclass __P((Elf *__elf)); + +extern size_t gelf_fsize __P((Elf *__elf, Elf_Type __type, size_t __count, unsigned __ver)); + +extern Elf_Data *gelf_xlatetof __P((Elf *__elf, Elf_Data *__dst, const Elf_Data *__src, unsigned __encode)); +extern Elf_Data *gelf_xlatetom __P((Elf *__elf, Elf_Data *__dst, const Elf_Data *__src, unsigned __encode)); + +extern GElf_Ehdr *gelf_getehdr __P((Elf *__elf, GElf_Ehdr *__dst)); +extern int gelf_update_ehdr __P((Elf *__elf, GElf_Ehdr *__src)); +extern unsigned long gelf_newehdr __P((Elf *__elf, int __elfclass)); + +extern GElf_Phdr *gelf_getphdr __P((Elf *__elf, int ndx, GElf_Phdr *__dst)); +extern int gelf_update_phdr __P((Elf *__elf, int ndx, GElf_Phdr *__src)); +extern unsigned long gelf_newphdr __P((Elf *__elf, size_t __phnum)); + +extern GElf_Shdr *gelf_getshdr __P((Elf_Scn *__scn, GElf_Shdr *__dst)); +extern int gelf_update_shdr __P((Elf_Scn *__scn, GElf_Shdr *__src)); + +extern GElf_Dyn *gelf_getdyn __P((Elf_Data *__src, int __ndx, GElf_Dyn *__dst)); +extern int gelf_update_dyn __P((Elf_Data *__dst, int __ndx, GElf_Dyn *__src)); + +extern GElf_Rel *gelf_getrel __P((Elf_Data *__src, int __ndx, GElf_Rel *__dst)); +extern int gelf_update_rel __P((Elf_Data *__dst, int __ndx, GElf_Rel *__src)); + +extern GElf_Rela *gelf_getrela __P((Elf_Data *__src, int __ndx, GElf_Rela *__dst)); +extern int gelf_update_rela __P((Elf_Data *__dst, int __ndx, GElf_Rela *__src)); + +extern GElf_Sym *gelf_getsym __P((Elf_Data *__src, int __ndx, GElf_Sym *__dst)); +extern int gelf_update_sym __P((Elf_Data *__dst, int __ndx, GElf_Sym *__src)); + +extern long gelf_checksum __P((Elf *__elf)); + +/* + * These functions aren't implemented (yet) + * +extern GElf_Move *gelf_getmove __P((Elf_Data *__src, int __ndx, GElf_Move *__src)); +extern int gelf_update_move __P((Elf_Data *__dst, int __ndx, GElf_Move *__src)); + * +extern GElf_Syminfo* gelf_getsyminfo __P((Elf_Data *__src, int __ndx, GElf_Syminfo *__dst)); +extern int gelf_update_syminfo __P((Elf_Data *__dst, int __ndx, GElf_Syminfo *__src)); + */ + +/* + * Extensions (not available in other versions of libelf) + */ +extern size_t gelf_msize __P((Elf *__elf, Elf_Type __type, size_t __count, unsigned __ver)); + +#endif /* __LIBELF64 */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _GELF_H */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/gelfehdr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/gelfehdr.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,140 @@ +/* + * gelfehdr.c - gelf_* translation functions. + * Copyright (C) 2000 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#if __LIBELF64 + +#ifndef lint +static const char rcsid[] = "@(#) $Id: gelfehdr.c,v 1.8 2006/07/07 22:16:43 michael Exp $"; +#endif /* lint */ + +#define check_and_copy(type, d, s, name, eret) \ + do { \ + if (sizeof((d)->name) < sizeof((s)->name) \ + && (type)(s)->name != (s)->name) { \ + seterr(ERROR_BADVALUE); \ + return (eret); \ + } \ + (d)->name = (type)(s)->name; \ + } while (0) + +GElf_Ehdr* +gelf_getehdr(Elf *elf, GElf_Ehdr *dst) { + GElf_Ehdr buf; + char *tmp; + + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + tmp = _elf_getehdr(elf, elf->e_class); + if (!tmp) { + return NULL; + } + if (!dst) { + dst = &buf; + } + if (elf->e_class == ELFCLASS64) { + *dst = *(Elf64_Ehdr*)tmp; + } + else if (elf->e_class == ELFCLASS32) { + Elf32_Ehdr *src = (Elf32_Ehdr*)tmp; + + memcpy(dst->e_ident, src->e_ident, EI_NIDENT); + check_and_copy(GElf_Half, dst, src, e_type, NULL); + check_and_copy(GElf_Half, dst, src, e_machine, NULL); + check_and_copy(GElf_Word, dst, src, e_version, NULL); + check_and_copy(GElf_Addr, dst, src, e_entry, NULL); + check_and_copy(GElf_Off, dst, src, e_phoff, NULL); + check_and_copy(GElf_Off, dst, src, e_shoff, NULL); + check_and_copy(GElf_Word, dst, src, e_flags, NULL); + check_and_copy(GElf_Half, dst, src, e_ehsize, NULL); + check_and_copy(GElf_Half, dst, src, e_phentsize, NULL); + check_and_copy(GElf_Half, dst, src, e_phnum, NULL); + check_and_copy(GElf_Half, dst, src, e_shentsize, NULL); + check_and_copy(GElf_Half, dst, src, e_shnum, NULL); + check_and_copy(GElf_Half, dst, src, e_shstrndx, NULL); + } + else { + if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return NULL; + } + if (dst == &buf) { + dst = (GElf_Ehdr*)malloc(sizeof(GElf_Ehdr)); + if (!dst) { + seterr(ERROR_MEM_EHDR); + return NULL; + } + *dst = buf; + } + return dst; +} + +int +gelf_update_ehdr(Elf *elf, GElf_Ehdr *src) { + char *tmp; + + if (!elf || !src) { + return 0; + } + elf_assert(elf->e_magic == ELF_MAGIC); + tmp = _elf_getehdr(elf, elf->e_class); + if (!tmp) { + return 0; + } + if (elf->e_class == ELFCLASS64) { + *(Elf64_Ehdr*)tmp = *src; + } + else if (elf->e_class == ELFCLASS32) { + Elf32_Ehdr *dst = (Elf32_Ehdr*)tmp; + + memcpy(dst->e_ident, src->e_ident, EI_NIDENT); + check_and_copy(Elf32_Half, dst, src, e_type, 0); + check_and_copy(Elf32_Half, dst, src, e_machine, 0); + check_and_copy(Elf32_Word, dst, src, e_version, 0); + check_and_copy(Elf32_Addr, dst, src, e_entry, 0); + check_and_copy(Elf32_Off, dst, src, e_phoff, 0); + check_and_copy(Elf32_Off, dst, src, e_shoff, 0); + check_and_copy(Elf32_Word, dst, src, e_flags, 0); + check_and_copy(Elf32_Half, dst, src, e_ehsize, 0); + check_and_copy(Elf32_Half, dst, src, e_phentsize, 0); + check_and_copy(Elf32_Half, dst, src, e_phnum, 0); + check_and_copy(Elf32_Half, dst, src, e_shentsize, 0); + check_and_copy(Elf32_Half, dst, src, e_shnum, 0); + check_and_copy(Elf32_Half, dst, src, e_shstrndx, 0); + } + else { + if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return 0; + } + return 1; +} + +#endif /* __LIBELF64 */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/gelfphdr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/gelfphdr.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,148 @@ +/* + * gelfphdr.c - gelf_* translation functions. + * Copyright (C) 2000 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#if __LIBELF64 + +#ifndef lint +static const char rcsid[] = "@(#) $Id: gelfphdr.c,v 1.8 2006/07/07 22:16:43 michael Exp $"; +#endif /* lint */ + +#define check_and_copy(type, d, s, name, eret) \ + do { \ + if (sizeof((d)->name) < sizeof((s)->name) \ + && (type)(s)->name != (s)->name) { \ + seterr(ERROR_BADVALUE); \ + return (eret); \ + } \ + (d)->name = (type)(s)->name; \ + } while (0) + +GElf_Phdr* +gelf_getphdr(Elf *elf, int ndx, GElf_Phdr *dst) { + GElf_Phdr buf; + char *tmp; + size_t n; + + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + tmp = _elf_getphdr(elf, elf->e_class); + if (!tmp) { + return NULL; + } + if (ndx < 0 || ndx >= elf->e_phnum) { + seterr(ERROR_BADINDEX); + return NULL; + } + n = _msize(elf->e_class, _elf_version, ELF_T_PHDR); + if (n == 0) { + seterr(ERROR_UNIMPLEMENTED); + return NULL; + } + if (!dst) { + dst = &buf; + } + if (elf->e_class == ELFCLASS64) { + *dst = *(Elf64_Phdr*)(tmp + ndx * n); + } + else if (elf->e_class == ELFCLASS32) { + Elf32_Phdr *src = (Elf32_Phdr*)(tmp + ndx * n); + + check_and_copy(GElf_Word, dst, src, p_type, NULL); + check_and_copy(GElf_Word, dst, src, p_flags, NULL); + check_and_copy(GElf_Off, dst, src, p_offset, NULL); + check_and_copy(GElf_Addr, dst, src, p_vaddr, NULL); + check_and_copy(GElf_Addr, dst, src, p_paddr, NULL); + check_and_copy(GElf_Xword, dst, src, p_filesz, NULL); + check_and_copy(GElf_Xword, dst, src, p_memsz, NULL); + check_and_copy(GElf_Xword, dst, src, p_align, NULL); + } + else { + if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return NULL; + } + if (dst == &buf) { + dst = (GElf_Phdr*)malloc(sizeof(GElf_Phdr)); + if (!dst) { + seterr(ERROR_MEM_PHDR); + return NULL; + } + *dst = buf; + } + return dst; +} + +int +gelf_update_phdr(Elf *elf, int ndx, GElf_Phdr *src) { + char *tmp; + size_t n; + + if (!elf || !src) { + return 0; + } + elf_assert(elf->e_magic == ELF_MAGIC); + tmp = _elf_getphdr(elf, elf->e_class); + if (!tmp) { + return 0; + } + if (ndx < 0 || ndx >= elf->e_phnum) { + seterr(ERROR_BADINDEX); + return 0; + } + n = _msize(elf->e_class, _elf_version, ELF_T_PHDR); + if (n == 0) { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + if (elf->e_class == ELFCLASS64) { + *(Elf64_Phdr*)(tmp + ndx * n) = *src; + } + else if (elf->e_class == ELFCLASS32) { + Elf32_Phdr *dst = (Elf32_Phdr*)(tmp + ndx * n); + + check_and_copy(Elf32_Word, dst, src, p_type, 0); + check_and_copy(Elf32_Off, dst, src, p_offset, 0); + check_and_copy(Elf32_Addr, dst, src, p_vaddr, 0); + check_and_copy(Elf32_Addr, dst, src, p_paddr, 0); + check_and_copy(Elf32_Word, dst, src, p_filesz, 0); + check_and_copy(Elf32_Word, dst, src, p_memsz, 0); + check_and_copy(Elf32_Word, dst, src, p_flags, 0); + check_and_copy(Elf32_Word, dst, src, p_align, 0); + } + else { + if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return 0; + } + return 1; +} + +#endif /* __LIBELF64 */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/gelfshdr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/gelfshdr.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,125 @@ +/* + * gelfshdr.c - gelf_* translation functions. + * Copyright (C) 2000 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#if __LIBELF64 + +#ifndef lint +static const char rcsid[] = "@(#) $Id: gelfshdr.c,v 1.9 2006/07/07 22:16:43 michael Exp $"; +#endif /* lint */ + +#define check_and_copy(type, d, s, name, eret) \ + do { \ + if (sizeof((d)->name) < sizeof((s)->name) \ + && (type)(s)->name != (s)->name) { \ + seterr(ERROR_BADVALUE); \ + return (eret); \ + } \ + (d)->name = (type)(s)->name; \ + } while (0) + +GElf_Shdr* +gelf_getshdr(Elf_Scn *scn, GElf_Shdr *dst) { + GElf_Shdr buf; + + if (!scn) { + return NULL; + } + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf); + elf_assert(scn->s_elf->e_magic == ELF_MAGIC); + if (!dst) { + dst = &buf; + } + if (scn->s_elf->e_class == ELFCLASS64) { + *dst = scn->s_shdr64; + } + else if (scn->s_elf->e_class == ELFCLASS32) { + Elf32_Shdr *src = &scn->s_shdr32; + + check_and_copy(GElf_Word, dst, src, sh_name, NULL); + check_and_copy(GElf_Word, dst, src, sh_type, NULL); + check_and_copy(GElf_Xword, dst, src, sh_flags, NULL); + check_and_copy(GElf_Addr, dst, src, sh_addr, NULL); + check_and_copy(GElf_Off, dst, src, sh_offset, NULL); + check_and_copy(GElf_Xword, dst, src, sh_size, NULL); + check_and_copy(GElf_Word, dst, src, sh_link, NULL); + check_and_copy(GElf_Word, dst, src, sh_info, NULL); + check_and_copy(GElf_Xword, dst, src, sh_addralign, NULL); + check_and_copy(GElf_Xword, dst, src, sh_entsize, NULL); + } + else { + if (valid_class(scn->s_elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return NULL; + } + if (dst == &buf) { + dst = (GElf_Shdr*)malloc(sizeof(GElf_Shdr)); + if (!dst) { + seterr(ERROR_MEM_SHDR); + return NULL; + } + *dst = buf; + } + return dst; +} + +int +gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *src) { + if (!scn || !src) { + return 0; + } + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf); + elf_assert(scn->s_elf->e_magic == ELF_MAGIC); + if (scn->s_elf->e_class == ELFCLASS64) { + scn->s_shdr64 = *src; + } + else if (scn->s_elf->e_class == ELFCLASS32) { + Elf32_Shdr *dst = &scn->s_shdr32; + + check_and_copy(Elf32_Word, dst, src, sh_name, 0); + check_and_copy(Elf32_Word, dst, src, sh_type, 0); + check_and_copy(Elf32_Word, dst, src, sh_flags, 0); + check_and_copy(Elf32_Addr, dst, src, sh_addr, 0); + check_and_copy(Elf32_Off, dst, src, sh_offset, 0); + check_and_copy(Elf32_Word, dst, src, sh_size, 0); + check_and_copy(Elf32_Word, dst, src, sh_link, 0); + check_and_copy(Elf32_Word, dst, src, sh_info, 0); + check_and_copy(Elf32_Word, dst, src, sh_addralign, 0); + check_and_copy(Elf32_Word, dst, src, sh_entsize, 0); + } + else { + if (valid_class(scn->s_elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return 0; + } + return 1; +} + +#endif /* __LIBELF64 */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/gelftrans.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/gelftrans.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,407 @@ +/* +gelftrans.c - gelf_* translation functions. +Copyright (C) 2000 - 2001 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#if __LIBELF64 + +#ifndef lint +static const char rcsid[] = "@(#) $Id: gelftrans.c,v 1.9 2005/05/21 15:39:23 michael Exp $"; +#endif /* lint */ + +#define check_and_copy(type, d, s, name, eret) \ + do { \ + if (sizeof((d)->name) < sizeof((s)->name) \ + && (type)(s)->name != (s)->name) { \ + seterr(ERROR_BADVALUE); \ + return (eret); \ + } \ + (d)->name = (type)(s)->name; \ + } while (0) + +/* + * These macros are missing on some Linux systems + */ +#if !defined(ELF32_R_SYM) || !defined(ELF32_R_TYPE) || !defined(ELF32_R_INFO) +# undef ELF32_R_SYM +# undef ELF32_R_TYPE +# undef ELF32_R_INFO +# define ELF32_R_SYM(i) ((i)>>8) +# define ELF32_R_TYPE(i) ((unsigned char)(i)) +# define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t)) +#endif /* !defined(...) */ + +#if !defined(ELF64_R_SYM) || !defined(ELF64_R_TYPE) || !defined(ELF64_R_INFO) +# undef ELF64_R_SYM +# undef ELF64_R_TYPE +# undef ELF64_R_INFO +# define ELF64_R_SYM(i) ((i)>>32) +# define ELF64_R_TYPE(i) ((i)&0xffffffffL) +# define ELF64_R_INFO(s,t) (((Elf64_Xword)(s)<<32)+((t)&0xffffffffL)) +#endif /* !defined(...) */ + +static char* +get_addr_and_class(const Elf_Data *data, int ndx, Elf_Type type, unsigned *cls) { + Scn_Data *sd = (Scn_Data*)data; + Elf_Scn *scn; + Elf *elf; + size_t n; + + if (!sd) { + return NULL; + } + elf_assert(sd->sd_magic == DATA_MAGIC); + scn = sd->sd_scn; + elf_assert(scn); + elf_assert(scn->s_magic == SCN_MAGIC); + elf = scn->s_elf; + elf_assert(elf); + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + return NULL; + } + if (!valid_class(elf->e_class)) { + seterr(ERROR_UNKNOWN_CLASS); + return NULL; + } + if (data->d_type != type) { + seterr(ERROR_BADTYPE); + return NULL; + } + n = _msize(elf->e_class, data->d_version, type); + if (n == 0) { + seterr(ERROR_UNIMPLEMENTED); + return NULL; + } + if (ndx < 0 || data->d_size < (ndx + 1) * n) { + seterr(ERROR_BADINDEX); + return NULL; + } + if (!data->d_buf) { + seterr(ERROR_NULLBUF); + return NULL; + } + if (cls) { + *cls = elf->e_class; + } + return (char*)data->d_buf + n * ndx; +} + +GElf_Sym* +gelf_getsym(Elf_Data *src, int ndx, GElf_Sym *dst) { + GElf_Sym buf; + unsigned cls; + char *tmp; + + if (!dst) { + dst = &buf; + } + tmp = get_addr_and_class(src, ndx, ELF_T_SYM, &cls); + if (!tmp) { + return NULL; + } + if (cls == ELFCLASS64) { + *dst = *(Elf64_Sym*)tmp; + } + else if (cls == ELFCLASS32) { + Elf32_Sym *src = (Elf32_Sym*)tmp; + + check_and_copy(GElf_Word, dst, src, st_name, NULL); + check_and_copy(unsigned char, dst, src, st_info, NULL); + check_and_copy(unsigned char, dst, src, st_other, NULL); + check_and_copy(GElf_Half, dst, src, st_shndx, NULL); + check_and_copy(GElf_Addr, dst, src, st_value, NULL); + check_and_copy(GElf_Xword, dst, src, st_size, NULL); + } + else { + seterr(ERROR_UNIMPLEMENTED); + return NULL; + } + if (dst == &buf) { + dst = (GElf_Sym*)malloc(sizeof(GElf_Sym)); + if (!dst) { + seterr(ERROR_MEM_SYM); + return NULL; + } + *dst = buf; + } + return dst; +} + +int +gelf_update_sym(Elf_Data *dst, int ndx, GElf_Sym *src) { + unsigned cls; + char *tmp; + + tmp = get_addr_and_class(dst, ndx, ELF_T_SYM, &cls); + if (!tmp) { + return 0; + } + if (cls == ELFCLASS64) { + *(Elf64_Sym*)tmp = *src; + } + else if (cls == ELFCLASS32) { + Elf32_Sym *dst = (Elf32_Sym*)tmp; + + check_and_copy(Elf32_Word, dst, src, st_name, 0); + check_and_copy(Elf32_Addr, dst, src, st_value, 0); + check_and_copy(Elf32_Word, dst, src, st_size, 0); + check_and_copy(unsigned char, dst, src, st_info, 0); + check_and_copy(unsigned char, dst, src, st_other, 0); + check_and_copy(Elf32_Half, dst, src, st_shndx, 0); + } + else { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + return 1; +} + +GElf_Dyn* +gelf_getdyn(Elf_Data *src, int ndx, GElf_Dyn *dst) { + GElf_Dyn buf; + unsigned cls; + char *tmp; + + if (!dst) { + dst = &buf; + } + tmp = get_addr_and_class(src, ndx, ELF_T_DYN, &cls); + if (!tmp) { + return NULL; + } + if (cls == ELFCLASS64) { + *dst = *(Elf64_Dyn*)tmp; + } + else if (cls == ELFCLASS32) { + Elf32_Dyn *src = (Elf32_Dyn*)tmp; + + check_and_copy(GElf_Sxword, dst, src, d_tag, NULL); + check_and_copy(GElf_Xword, dst, src, d_un.d_val, NULL); + } + else { + seterr(ERROR_UNIMPLEMENTED); + return NULL; + } + if (dst == &buf) { + dst = (GElf_Dyn*)malloc(sizeof(GElf_Dyn)); + if (!dst) { + seterr(ERROR_MEM_DYN); + return NULL; + } + *dst = buf; + } + return dst; +} + +int +gelf_update_dyn(Elf_Data *dst, int ndx, GElf_Dyn *src) { + unsigned cls; + char *tmp; + + tmp = get_addr_and_class(dst, ndx, ELF_T_DYN, &cls); + if (!tmp) { + return 0; + } + if (cls == ELFCLASS64) { + *(Elf64_Dyn*)tmp = *src; + } + else if (cls == ELFCLASS32) { + Elf32_Dyn *dst = (Elf32_Dyn*)tmp; + + check_and_copy(Elf32_Sword, dst, src, d_tag, 0); + check_and_copy(Elf32_Word, dst, src, d_un.d_val, 0); + } + else { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + return 1; +} + +GElf_Rela* +gelf_getrela(Elf_Data *src, int ndx, GElf_Rela *dst) { + GElf_Rela buf; + unsigned cls; + char *tmp; + + if (!dst) { + dst = &buf; + } + tmp = get_addr_and_class(src, ndx, ELF_T_RELA, &cls); + if (!tmp) { + return NULL; + } + if (cls == ELFCLASS64) { + *dst = *(Elf64_Rela*)tmp; + } + else if (cls == ELFCLASS32) { + Elf32_Rela *src = (Elf32_Rela*)tmp; + + check_and_copy(GElf_Addr, dst, src, r_offset, NULL); + dst->r_info = ELF64_R_INFO((Elf64_Xword)ELF32_R_SYM(src->r_info), + (Elf64_Xword)ELF32_R_TYPE(src->r_info)); + check_and_copy(GElf_Sxword, dst, src, r_addend, NULL); + } + else { + seterr(ERROR_UNIMPLEMENTED); + return NULL; + } + if (dst == &buf) { + dst = (GElf_Rela*)malloc(sizeof(GElf_Rela)); + if (!dst) { + seterr(ERROR_MEM_RELA); + return NULL; + } + *dst = buf; + } + return dst; +} + +int +gelf_update_rela(Elf_Data *dst, int ndx, GElf_Rela *src) { + unsigned cls; + char *tmp; + + tmp = get_addr_and_class(dst, ndx, ELF_T_RELA, &cls); + if (!tmp) { + return 0; + } + if (cls == ELFCLASS64) { + *(Elf64_Rela*)tmp = *src; + } + else if (cls == ELFCLASS32) { + Elf32_Rela *dst = (Elf32_Rela*)tmp; + + check_and_copy(Elf32_Addr, dst, src, r_offset, 0); + if (ELF64_R_SYM(src->r_info) > 0xffffffUL + || ELF64_R_TYPE(src->r_info) > 0xffUL) { + seterr(ERROR_BADVALUE); + return 0; + } + dst->r_info = ELF32_R_INFO((Elf32_Word)ELF64_R_SYM(src->r_info), + (Elf32_Word)ELF64_R_TYPE(src->r_info)); + check_and_copy(Elf32_Sword, dst, src, r_addend, 0); + } + else { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + return 1; +} + +GElf_Rel* +gelf_getrel(Elf_Data *src, int ndx, GElf_Rel *dst) { + GElf_Rel buf; + unsigned cls; + char *tmp; + + if (!dst) { + dst = &buf; + } + tmp = get_addr_and_class(src, ndx, ELF_T_REL, &cls); + if (!tmp) { + return NULL; + } + if (cls == ELFCLASS64) { + *dst = *(Elf64_Rel*)tmp; + } + else if (cls == ELFCLASS32) { + Elf32_Rel *src = (Elf32_Rel*)tmp; + + check_and_copy(GElf_Addr, dst, src, r_offset, NULL); + dst->r_info = ELF64_R_INFO((Elf64_Xword)ELF32_R_SYM(src->r_info), + (Elf64_Xword)ELF32_R_TYPE(src->r_info)); + } + else { + seterr(ERROR_UNIMPLEMENTED); + return NULL; + } + if (dst == &buf) { + dst = (GElf_Rel*)malloc(sizeof(GElf_Rel)); + if (!dst) { + seterr(ERROR_MEM_REL); + return NULL; + } + *dst = buf; + } + return dst; +} + +int +gelf_update_rel(Elf_Data *dst, int ndx, GElf_Rel *src) { + unsigned cls; + char *tmp; + + tmp = get_addr_and_class(dst, ndx, ELF_T_REL, &cls); + if (!tmp) { + return 0; + } + if (cls == ELFCLASS64) { + *(Elf64_Rel*)tmp = *src; + } + else if (cls == ELFCLASS32) { + Elf32_Rel *dst = (Elf32_Rel*)tmp; + + check_and_copy(Elf32_Addr, dst, src, r_offset, 0); + if (ELF64_R_SYM(src->r_info) > 0xffffffUL + || ELF64_R_TYPE(src->r_info) > 0xffUL) { + seterr(ERROR_BADVALUE); + return 0; + } + dst->r_info = ELF32_R_INFO((Elf32_Word)ELF64_R_SYM(src->r_info), + (Elf32_Word)ELF64_R_TYPE(src->r_info)); + } + else { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + return 1; +} + +#if 0 + +GElf_Syminfo* +gelf_getsyminfo(Elf_Data *src, int ndx, GElf_Syminfo *dst) { + seterr(ERROR_UNIMPLEMENTED); + return NULL; +} + +int +gelf_update_syminfo(Elf_Data *dst, int ndx, GElf_Syminfo *src) { + seterr(ERROR_UNIMPLEMENTED); + return 0; +} + +GElf_Move* +gelf_getmove(Elf_Data *src, int ndx, GElf_Move *src) { + seterr(ERROR_UNIMPLEMENTED); + return NULL; +} + +int +gelf_update_move(Elf_Data *dst, int ndx, GElf_Move *src) { + seterr(ERROR_UNIMPLEMENTED); + return 0; +} + +#endif + +#endif /* __LIBELF64 */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/getarhdr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/getarhdr.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,37 @@ +/* +getarhdr.c - implementation of the elf_getarhdr(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: getarhdr.c,v 1.6 2005/05/21 15:39:23 michael Exp $"; +#endif /* lint */ + +Elf_Arhdr* +elf_getarhdr(Elf *elf) { + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_arhdr) { + return elf->e_arhdr; + } + seterr(ERROR_NOTARCHIVE); + return NULL; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/getarsym.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/getarsym.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,87 @@ +/* + * getarsym.c - implementation of the elf_getarsym(3) function. + * Copyright (C) 1995 - 1998, 2004 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: getarsym.c,v 1.8 2005/05/21 15:39:23 michael Exp $"; +#endif /* lint */ + +Elf_Arsym* +elf_getarsym(Elf *elf, size_t *ptr) { + Elf_Arsym *syms; + size_t count; + size_t tmp; + size_t i; + char *s; + char *e; + + if (!ptr) { + ptr = &tmp; + } + *ptr = 0; + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_AR) { + seterr(ERROR_NOTARCHIVE); + return NULL; + } + if (elf->e_symtab && !elf->e_free_syms) { + if (elf->e_symlen < 4) { + seterr(ERROR_SIZE_ARSYMTAB); + return NULL; + } + count = __load_u32M(elf->e_symtab); + if (elf->e_symlen < 4 * (count + 1)) { + seterr(ERROR_SIZE_ARSYMTAB); + return NULL; + } + if (!(syms = (Elf_Arsym*)malloc((count + 1) * sizeof(*syms)))) { + seterr(ERROR_MEM_ARSYMTAB); + return NULL; + } + s = elf->e_symtab + 4 * (count + 1); + e = elf->e_symtab + elf->e_symlen; + for (i = 0; i < count; i++, s++) { + syms[i].as_name = s; + while (s < e && *s) { + s++; + } + if (s >= e) { + seterr(ERROR_SIZE_ARSYMTAB); + free(syms); + return NULL; + } + elf_assert(!*s); + syms[i].as_hash = elf_hash((unsigned char*)syms[i].as_name); + syms[i].as_off = __load_u32M(elf->e_symtab + 4 * (i + 1)); + } + syms[count].as_name = NULL; + syms[count].as_hash = ~0UL; + syms[count].as_off = 0; + elf->e_symtab = (char*)syms; + elf->e_symlen = count + 1; + elf->e_free_syms = 1; + } + *ptr = elf->e_symlen; + return (Elf_Arsym*)elf->e_symtab; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/getbase.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/getbase.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,33 @@ +/* +getbase.c - implementation of the elf_getbase(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: getbase.c,v 1.6 2005/05/21 15:39:23 michael Exp $"; +#endif /* lint */ + +off_t +elf_getbase(Elf *elf) { + if (!elf) { + return -1; + } + elf_assert(elf->e_magic == ELF_MAGIC); + return (off_t)elf->e_base; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/getdata.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/getdata.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,157 @@ +/* +getdata.c - implementation of the elf_getdata(3) function. +Copyright (C) 1995 - 2001 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: getdata.c,v 1.12 2005/05/21 15:39:23 michael Exp $"; +#endif /* lint */ + +static Elf_Data* +_elf_cook_scn(Elf *elf, Elf_Scn *scn, Scn_Data *sd) { + Elf_Data dst; + Elf_Data src; + int flag = 0; + size_t dlen; + + elf_assert(elf->e_data); + + /* + * Prepare source + */ + src = sd->sd_data; + src.d_version = elf->e_version; + if (elf->e_rawdata) { + src.d_buf = elf->e_rawdata + scn->s_offset; + } + else { + src.d_buf = elf->e_data + scn->s_offset; + } + + /* + * Prepare destination (needs prepared source!) + */ + dst = sd->sd_data; + if (elf->e_class == ELFCLASS32) { + dlen = _elf32_xltsize(&src, dst.d_version, elf->e_encoding, 0); + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + dlen = _elf64_xltsize(&src, dst.d_version, elf->e_encoding, 0); + } +#endif /* __LIBELF64 */ + else { + elf_assert(valid_class(elf->e_class)); + seterr(ERROR_UNIMPLEMENTED); + return NULL; + } + if (dlen == (size_t)-1) { + return NULL; + } + dst.d_size = dlen; + if (elf->e_rawdata != elf->e_data && dst.d_size <= src.d_size) { + dst.d_buf = elf->e_data + scn->s_offset; + } + else if (!(dst.d_buf = malloc(dst.d_size))) { + seterr(ERROR_MEM_SCNDATA); + return NULL; + } + else { + flag = 1; + } + + /* + * Translate data + */ + if (_elf_xlatetom(elf, &dst, &src)) { + sd->sd_memdata = (char*)dst.d_buf; + sd->sd_data = dst; + if (!(sd->sd_free_data = flag)) { + elf->e_cooked = 1; + } + return &sd->sd_data; + } + + if (flag) { + free(dst.d_buf); + } + return NULL; +} + +Elf_Data* +elf_getdata(Elf_Scn *scn, Elf_Data *data) { + Scn_Data *sd; + Elf *elf; + + if (!scn) { + return NULL; + } + elf_assert(scn->s_magic == SCN_MAGIC); + if (scn->s_index == SHN_UNDEF) { + seterr(ERROR_NULLSCN); + } + else if (data) { + for (sd = scn->s_data_1; sd; sd = sd->sd_link) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + if (data == &sd->sd_data) { + /* + * sd_link allocated by elf_newdata(). + */ + return &sd->sd_link->sd_data; + } + } + seterr(ERROR_SCNDATAMISMATCH); + } + else if ((sd = scn->s_data_1)) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + elf = scn->s_elf; + elf_assert(elf); + elf_assert(elf->e_magic == ELF_MAGIC); + if (sd->sd_freeme) { + /* allocated by elf_newdata() */ + return &sd->sd_data; + } + else if (scn->s_type == SHT_NULL) { + seterr(ERROR_NULLSCN); + } + else if (sd->sd_memdata) { + /* already cooked */ + return &sd->sd_data; + } + else if (scn->s_offset < 0 || scn->s_offset > elf->e_size) { + seterr(ERROR_OUTSIDE); + } + else if (scn->s_type == SHT_NOBITS || !scn->s_size) { + /* no data to read */ + return &sd->sd_data; + } + else if (scn->s_offset + scn->s_size > elf->e_size) { + seterr(ERROR_TRUNC_SCN); + } + else if (valid_class(elf->e_class)) { + return _elf_cook_scn(elf, scn, sd); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + } + return NULL; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/getident.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/getident.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,48 @@ +/* +getident.c - implementation of the elf_getident(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: getident.c,v 1.6 2005/05/21 15:39:23 michael Exp $"; +#endif /* lint */ + +char* +elf_getident(Elf *elf, size_t *ptr) { + size_t tmp; + + if (!ptr) { + ptr = &tmp; + } + if (!elf) { + *ptr = 0; + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + *ptr = elf->e_idlen; + return elf->e_data; + } + if (elf->e_ehdr || _elf_cook(elf)) { + *ptr = elf->e_idlen; + return elf->e_ehdr; + } + *ptr = 0; + return NULL; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/getscn.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/getscn.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,48 @@ +/* +getscn.c - implementation of the elf_getscn(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: getscn.c,v 1.6 2005/05/21 15:39:23 michael Exp $"; +#endif /* lint */ + +Elf_Scn* +elf_getscn(Elf *elf, size_t index) { + Elf_Scn *scn; + + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_ehdr || _elf_cook(elf)) { + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf == elf); + if (scn->s_index == index) { + return scn; + } + } + seterr(ERROR_NOSUCHSCN); + } + return NULL; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/hash.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/hash.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,38 @@ +/* +hash.c - implementation of the elf_hash(3) function. +Copyright (C) 1995 - 2002 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: hash.c,v 1.9 2005/05/21 15:39:23 michael Exp $"; +#endif /* lint */ + +unsigned long +elf_hash(const unsigned char *name) { + unsigned long hash = 0; + unsigned long tmp; + + while (*name) { + hash = (hash << 4) + (unsigned char)*name++; + if ((tmp = hash & 0xf0000000)) { + hash ^= tmp | (tmp >> 24); + } + } + return hash; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/input.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/input.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,106 @@ +/* + * input.c - low-level input for libelf. + * Copyright (C) 1995 - 2001, 2005 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: input.c,v 1.10 2005/10/20 21:08:02 michael Exp $"; +#endif /* lint */ + +#include + +#if HAVE_MMAP +#include +#endif /* HAVE_MMAP */ + +static int +xread(int fd, char *buffer, size_t len) { + size_t done = 0; + size_t n; + + while (done < len) { + n = read(fd, buffer + done, len - done); + if (n == 0) { + /* premature end of file */ + return -1; + } + else if (n != (size_t)-1) { + /* some bytes read, continue */ + done += n; + } + else if (errno != EAGAIN && errno != EINTR) { + /* real error */ + return -1; + } + } + return 0; +} + +void* +_elf_read(Elf *elf, void *buffer, size_t off, size_t len) { + void *tmp; + + elf_assert(elf); + elf_assert(elf->e_magic == ELF_MAGIC); + elf_assert(off >= 0 && off + len <= elf->e_size); + if (elf->e_disabled) { + seterr(ERROR_FDDISABLED); + } + else if (len) { + off += elf->e_base; + if (lseek(elf->e_fd, (off_t)off, SEEK_SET) != (off_t)off) { + seterr(ERROR_IO_SEEK); + } + else if (!(tmp = buffer) && !(tmp = malloc(len))) { + seterr(ERROR_IO_2BIG); + } + else if (xread(elf->e_fd, tmp, len)) { + seterr(ERROR_IO_READ); + if (tmp != buffer) { + free(tmp); + } + } + else { + return tmp; + } + } + return NULL; +} + +void* +_elf_mmap(Elf *elf) { +#if HAVE_MMAP + void *tmp; + + elf_assert(elf); + elf_assert(elf->e_magic == ELF_MAGIC); + elf_assert(elf->e_base == 0); + if (elf->e_disabled) { + seterr(ERROR_FDDISABLED); + } + else if (elf->e_size) { + tmp = (void*)mmap(0, elf->e_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE, elf->e_fd, 0); + if (tmp != (void*)-1) { + return tmp; + } + } +#endif /* HAVE_MMAP */ + return NULL; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/kind.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/kind.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,33 @@ +/* +kind.c - implementation of the elf_kind(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: kind.c,v 1.6 2005/05/21 15:39:24 michael Exp $"; +#endif /* lint */ + +Elf_Kind +elf_kind(Elf *elf) { + if (!elf) { + return ELF_K_NONE; + } + elf_assert(elf->e_magic == ELF_MAGIC); + return elf->e_kind; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/libelf.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/libelf.def Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,82 @@ +LIBRARY libelf +VERSION 0.8 +EXPORTS + elf_begin + elf_cntl + elf_delscn + elf_end + elf_errmsg + elf_errno + elf_fill + elf_flagdata + elf_flagehdr + elf_flagelf + elf_flagphdr + elf_flagscn + elf_flagshdr + elf_getarhdr + elf_getarsym + elf_getbase + elf_getdata + elf_getident + elf_getscn + elf_hash + elf_kind + elf_memory + elf_ndxscn + elf_newdata + elf_newscn + elf_next + elf_nextscn + elf_rand + elf_rawdata + elf_rawfile + elf_strptr + elf_update + elf_version + elf32_checksum + elf32_fsize + elf32_getehdr + elf32_getphdr + elf32_getshdr + elf32_newehdr + elf32_newphdr + elf32_xlatetof + elf32_xlatetom + elf64_checksum + elf64_fsize + elf64_getehdr + elf64_getphdr + elf64_getshdr + elf64_newehdr + elf64_newphdr + elf64_xlatetof + elf64_xlatetom + elfx_movscn + elfx_remscn + gelf_checksum + gelf_fsize + gelf_getclass + gelf_getdyn + gelf_getehdr + gelf_getphdr + gelf_getrel + gelf_getrela + gelf_getshdr + gelf_getsym + gelf_msize + gelf_newehdr + gelf_newphdr + gelf_update_dyn + gelf_update_ehdr + gelf_update_phdr + gelf_update_rel + gelf_update_rela + gelf_update_shdr + gelf_update_sym + gelf_xlatetof + gelf_xlatetom + elf_getphnum + elf_getshnum + elf_getshstrndx + elfx_update_shstrndx diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/libelf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/libelf.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,284 @@ +/* + * libelf.h - public header file for libelf. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* @(#) $Id: libelf.h,v 1.26 2006/09/02 14:11:48 michael Exp $ */ + +#ifndef _LIBELF_H +#define _LIBELF_H + +#include /* for size_t */ +#include + +#if __LIBELF_INTERNAL__ +#include +#else /* __LIBELF_INTERNAL__ */ +#include +#endif /* __LIBELF_INTERNAL__ */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef __P +# if (__STDC__ + 0) || defined(__cplusplus) || defined(_WIN32) +# define __P(args) args +# else /* __STDC__ || defined(__cplusplus) */ +# define __P(args) () +# endif /* __STDC__ || defined(__cplusplus) */ +#endif /* __P */ + +/* + * Commands + */ +typedef enum { + ELF_C_NULL = 0, /* must be first, 0 */ + ELF_C_READ, + ELF_C_WRITE, + ELF_C_CLR, + ELF_C_SET, + ELF_C_FDDONE, + ELF_C_FDREAD, + ELF_C_RDWR, + ELF_C_NUM /* must be last */ +} Elf_Cmd; + +/* + * Flags + */ +#define ELF_F_DIRTY 0x1 +#define ELF_F_LAYOUT 0x4 + +/* + * File types + */ +typedef enum { + ELF_K_NONE = 0, /* must be first, 0 */ + ELF_K_AR, + ELF_K_COFF, + ELF_K_ELF, + ELF_K_NUM /* must be last */ +} Elf_Kind; + +/* + * Data types + */ +typedef enum { + ELF_T_BYTE = 0, /* must be first, 0 */ + ELF_T_ADDR, + ELF_T_DYN, + ELF_T_EHDR, + ELF_T_HALF, + ELF_T_OFF, + ELF_T_PHDR, + ELF_T_RELA, + ELF_T_REL, + ELF_T_SHDR, + ELF_T_SWORD, + ELF_T_SYM, + ELF_T_WORD, + /* + * New stuff for 64-bit. + * + * Most implementations add ELF_T_SXWORD after ELF_T_SWORD + * which breaks binary compatibility with earlier versions. + * If this causes problems for you, contact me. + */ + ELF_T_SXWORD, + ELF_T_XWORD, + /* + * Symbol versioning. Sun broke binary compatibility (again!), + * but I won't. + */ + ELF_T_VDEF, + ELF_T_VNEED, + ELF_T_NUM /* must be last */ +} Elf_Type; + +/* + * Elf descriptor + */ +typedef struct Elf Elf; + +/* + * Section descriptor + */ +typedef struct Elf_Scn Elf_Scn; + +/* + * Archive member header + */ +typedef struct { + char* ar_name; + time_t ar_date; + long ar_uid; + long ar_gid; + unsigned long ar_mode; + off_t ar_size; + char* ar_rawname; +} Elf_Arhdr; + +/* + * Archive symbol table + */ +typedef struct { + char* as_name; + size_t as_off; + unsigned long as_hash; +} Elf_Arsym; + +/* + * Data descriptor + */ +typedef struct { + void* d_buf; + Elf_Type d_type; + size_t d_size; + off_t d_off; + size_t d_align; + unsigned d_version; +} Elf_Data; + +/* + * Function declarations + */ +extern Elf *elf_begin __P((int __fd, Elf_Cmd __cmd, Elf *__ref)); +extern Elf *elf_memory __P((char *__image, size_t __size)); +extern int elf_cntl __P((Elf *__elf, Elf_Cmd __cmd)); +extern int elf_end __P((Elf *__elf)); +extern const char *elf_errmsg __P((int __err)); +extern int elf_errno __P((void)); +extern void elf_fill __P((int __fill)); +extern unsigned elf_flagdata __P((Elf_Data *__data, Elf_Cmd __cmd, + unsigned __flags)); +extern unsigned elf_flagehdr __P((Elf *__elf, Elf_Cmd __cmd, + unsigned __flags)); +extern unsigned elf_flagelf __P((Elf *__elf, Elf_Cmd __cmd, + unsigned __flags)); +extern unsigned elf_flagphdr __P((Elf *__elf, Elf_Cmd __cmd, + unsigned __flags)); +extern unsigned elf_flagscn __P((Elf_Scn *__scn, Elf_Cmd __cmd, + unsigned __flags)); +extern unsigned elf_flagshdr __P((Elf_Scn *__scn, Elf_Cmd __cmd, + unsigned __flags)); +extern size_t elf32_fsize __P((Elf_Type __type, size_t __count, + unsigned __ver)); +extern Elf_Arhdr *elf_getarhdr __P((Elf *__elf)); +extern Elf_Arsym *elf_getarsym __P((Elf *__elf, size_t *__ptr)); +extern off_t elf_getbase __P((Elf *__elf)); +extern Elf_Data *elf_getdata __P((Elf_Scn *__scn, Elf_Data *__data)); +extern Elf32_Ehdr *elf32_getehdr __P((Elf *__elf)); +extern char *elf_getident __P((Elf *__elf, size_t *__ptr)); +extern Elf32_Phdr *elf32_getphdr __P((Elf *__elf)); +extern Elf_Scn *elf_getscn __P((Elf *__elf, size_t __index)); +extern Elf32_Shdr *elf32_getshdr __P((Elf_Scn *__scn)); +extern unsigned long elf_hash __P((const unsigned char *__name)); +extern Elf_Kind elf_kind __P((Elf *__elf)); +extern size_t elf_ndxscn __P((Elf_Scn *__scn)); +extern Elf_Data *elf_newdata __P((Elf_Scn *__scn)); +extern Elf32_Ehdr *elf32_newehdr __P((Elf *__elf)); +extern Elf32_Phdr *elf32_newphdr __P((Elf *__elf, size_t __count)); +extern Elf_Scn *elf_newscn __P((Elf *__elf)); +extern Elf_Cmd elf_next __P((Elf *__elf)); +extern Elf_Scn *elf_nextscn __P((Elf *__elf, Elf_Scn *__scn)); +extern size_t elf_rand __P((Elf *__elf, size_t __offset)); +extern Elf_Data *elf_rawdata __P((Elf_Scn *__scn, Elf_Data *__data)); +extern char *elf_rawfile __P((Elf *__elf, size_t *__ptr)); +extern char *elf_strptr __P((Elf *__elf, size_t __section, size_t __offset)); +extern off_t elf_update __P((Elf *__elf, Elf_Cmd __cmd)); +extern unsigned elf_version __P((unsigned __ver)); +extern Elf_Data *elf32_xlatetof __P((Elf_Data *__dst, const Elf_Data *__src, + unsigned __encode)); +extern Elf_Data *elf32_xlatetom __P((Elf_Data *__dst, const Elf_Data *__src, + unsigned __encode)); + +/* + * Additional functions found on Solaris + */ +extern long elf32_checksum __P((Elf *__elf)); + +#if __LIBELF64 +/* + * 64-bit ELF functions + * Not available on all platforms + */ +extern Elf64_Ehdr *elf64_getehdr __P((Elf *__elf)); +extern Elf64_Ehdr *elf64_newehdr __P((Elf *__elf)); +extern Elf64_Phdr *elf64_getphdr __P((Elf *__elf)); +extern Elf64_Phdr *elf64_newphdr __P((Elf *__elf, size_t __count)); +extern Elf64_Shdr *elf64_getshdr __P((Elf_Scn *__scn)); +extern size_t elf64_fsize __P((Elf_Type __type, size_t __count, + unsigned __ver)); +extern Elf_Data *elf64_xlatetof __P((Elf_Data *__dst, const Elf_Data *__src, + unsigned __encode)); +extern Elf_Data *elf64_xlatetom __P((Elf_Data *__dst, const Elf_Data *__src, + unsigned __encode)); + +/* + * Additional functions found on Solaris + */ +extern long elf64_checksum __P((Elf *__elf)); + +#endif /* __LIBELF64 */ + +/* + * ELF format extensions + * + * These functions return 0 on failure, 1 on success. + */ +extern int elf_getphnum __P((Elf *__elf, size_t *__resultp)); +extern int elf_getshnum __P((Elf *__elf, size_t *__resultp)); +extern int elf_getshstrndx __P((Elf *__elf, size_t *__resultp)); + +/* + * Convenience functions + * + * elfx_update_shstrndx is elf_getshstrndx's counterpart. + * It should be used to set the e_shstrndx member. + * There is no update function for e_shnum or e_phnum + * because libelf handles them internally. + */ +extern int elfx_update_shstrndx __P((Elf *__elf, size_t __index)); + +/* + * Experimental extensions: + * + * elfx_movscn() moves section `__scn' directly after section `__after'. + * elfx_remscn() removes section `__scn'. Both functions update + * the section indices; elfx_remscn() also adjusts the ELF header's + * e_shnum member. The application is responsible for updating other + * data (in particular, e_shstrndx and the section headers' sh_link and + * sh_info members). + * + * elfx_movscn() returns the new index of the moved section. + * elfx_remscn() returns the original index of the removed section. + * A return value of zero indicates an error. + */ +extern size_t elfx_movscn __P((Elf *__elf, Elf_Scn *__scn, Elf_Scn *__after)); +extern size_t elfx_remscn __P((Elf *__elf, Elf_Scn *__scn)); + +/* + * elf_delscn() is obsolete. Please use elfx_remscn() instead. + */ +extern size_t elf_delscn __P((Elf *__elf, Elf_Scn *__scn)); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _LIBELF_H */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/memset.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/memset.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,53 @@ +/* + * memset.c - replacement for memset(3), using duff's device. + * Copyright (C) 1995 - 2004 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if HAVE_CONFIG_H +# include +#endif /* HAVE_CONFIG_H */ + +#ifndef lint +static const char rcsid[] = "@(#) $Id: memset.c,v 1.10 2005/05/21 15:39:24 michael Exp $"; +#endif /* lint */ + +#include /* for size_t */ +#include + +void* +_elf_memset(void *s, int c, size_t n) { + char *t = (char*)s; + + if (n) { + switch (n % 8u) { + do { + n -= 8; + default: + case 0: *t++ = (char)c; + case 7: *t++ = (char)c; + case 6: *t++ = (char)c; + case 5: *t++ = (char)c; + case 4: *t++ = (char)c; + case 3: *t++ = (char)c; + case 2: *t++ = (char)c; + case 1: *t++ = (char)c; + } + while (n > 8); + } + } + return s; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/ndxscn.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/ndxscn.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,33 @@ +/* +ndxscn.c - implementation of the elf_ndxscn(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: ndxscn.c,v 1.6 2005/05/21 15:39:24 michael Exp $"; +#endif /* lint */ + +size_t +elf_ndxscn(Elf_Scn *scn) { + if (!scn) { + return SHN_UNDEF; + } + elf_assert(scn->s_magic == SCN_MAGIC); + return scn->s_index; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/newdata.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/newdata.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,56 @@ +/* +newdata.c - implementation of the elf_newdata(3) function. +Copyright (C) 1995 - 2000 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: newdata.c,v 1.9 2005/05/21 15:39:24 michael Exp $"; +#endif /* lint */ + +Elf_Data* +elf_newdata(Elf_Scn *scn) { + Scn_Data *sd; + + if (!scn) { + return NULL; + } + elf_assert(scn->s_magic == SCN_MAGIC); + if (scn->s_index == SHN_UNDEF) { + seterr(ERROR_NULLSCN); + } + else if (!(sd = (Scn_Data*)malloc(sizeof(*sd)))) { + seterr(ERROR_MEM_SCNDATA); + } + else { + *sd = _elf_data_init; + sd->sd_scn = scn; + sd->sd_data_flags = ELF_F_DIRTY; + sd->sd_freeme = 1; + sd->sd_data.d_version = _elf_version; + if (scn->s_data_n) { + scn->s_data_n->sd_link = sd; + } + else { + scn->s_data_1 = sd; + } + scn->s_data_n = sd; + return &sd->sd_data; + } + return NULL; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/newscn.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/newscn.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,145 @@ +/* + * newscn.c - implementation of the elf_newscn(3) function. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: newscn.c,v 1.12 2006/07/07 22:17:01 michael Exp $"; +#endif /* lint */ + +int +_elf_update_shnum(Elf *elf, size_t shnum) { + size_t extshnum = 0; + Elf_Scn *scn; + + elf_assert(elf); + elf_assert(elf->e_ehdr); + scn = elf->e_scn_1; + elf_assert(scn); + elf_assert(scn->s_index == 0); + if (shnum >= SHN_LORESERVE) { + extshnum = shnum; + shnum = 0; + } + if (elf->e_class == ELFCLASS32) { + ((Elf32_Ehdr*)elf->e_ehdr)->e_shnum = shnum; + scn->s_shdr32.sh_size = extshnum; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + ((Elf64_Ehdr*)elf->e_ehdr)->e_shnum = shnum; + scn->s_shdr64.sh_size = extshnum; + } +#endif /* __LIBELF64 */ + else { + if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return -1; + } + elf->e_ehdr_flags |= ELF_F_DIRTY; + scn->s_shdr_flags |= ELF_F_DIRTY; + return 0; +} + +static Elf_Scn* +_makescn(Elf *elf, size_t index) { + Elf_Scn *scn; + + elf_assert(elf); + elf_assert(elf->e_magic == ELF_MAGIC); + elf_assert(elf->e_ehdr); + elf_assert(_elf_scn_init.s_magic == SCN_MAGIC); + if (!(scn = (Elf_Scn*)malloc(sizeof(*scn)))) { + seterr(ERROR_MEM_SCN); + return NULL; + } + *scn = _elf_scn_init; + scn->s_elf = elf; + scn->s_scn_flags = ELF_F_DIRTY; + scn->s_shdr_flags = ELF_F_DIRTY; + scn->s_freeme = 1; + scn->s_index = index; + return scn; +} + +Elf_Scn* +_elf_first_scn(Elf *elf) { + Elf_Scn *scn; + + elf_assert(elf); + elf_assert(elf->e_magic == ELF_MAGIC); + if ((scn = elf->e_scn_1)) { + return scn; + } + if ((scn = _makescn(elf, 0))) { + elf->e_scn_1 = elf->e_scn_n = scn; + if (_elf_update_shnum(elf, 1)) { + free(scn); + elf->e_scn_1 = elf->e_scn_n = scn = NULL; + } + } + return scn; +} + +static Elf_Scn* +_buildscn(Elf *elf) { + Elf_Scn *scn; + + if (!_elf_first_scn(elf)) { + return NULL; + } + scn = elf->e_scn_n; + elf_assert(scn); + if (!(scn = _makescn(elf, scn->s_index + 1))) { + return NULL; + } + if (_elf_update_shnum(elf, scn->s_index + 1)) { + free(scn); + return NULL; + } + elf->e_scn_n = elf->e_scn_n->s_link = scn; + return scn; +} + +Elf_Scn* +elf_newscn(Elf *elf) { + Elf_Scn *scn; + + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (!elf->e_readable && !elf->e_ehdr) { + seterr(ERROR_NOEHDR); + } + else if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (!elf->e_ehdr && !_elf_cook(elf)) { + return NULL; + } + else if ((scn = _buildscn(elf))) { + return scn; + } + return NULL; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/next.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/next.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,42 @@ +/* +next.c - implementation of the elf_next(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: next.c,v 1.6 2005/05/21 15:39:25 michael Exp $"; +#endif /* lint */ + +Elf_Cmd +elf_next(Elf *elf) { + if (!elf) { + return ELF_C_NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (!elf->e_parent) { + return ELF_C_NULL; + } + elf_assert(elf->e_parent->e_magic == ELF_MAGIC); + elf_assert(elf->e_parent->e_kind == ELF_K_AR); + elf->e_parent->e_off = elf->e_next; + if (elf->e_next == elf->e_parent->e_size) { + return ELF_C_NULL; + } + return ELF_C_READ; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/nextscn.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/nextscn.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,54 @@ +/* +nextscn.c - implementation of the elf_nextscn(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: nextscn.c,v 1.6 2005/05/21 15:39:25 michael Exp $"; +#endif /* lint */ + +Elf_Scn* +elf_nextscn(Elf *elf, Elf_Scn *scn) { + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (scn) { + elf_assert(scn->s_magic == SCN_MAGIC); + if (scn->s_elf == elf) { + return scn->s_link; + } + seterr(ERROR_ELFSCNMISMATCH); + } + else if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_ehdr || _elf_cook(elf)) { + elf_assert(elf->e_ehdr); + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf == elf); + if (scn->s_index == 1) { + return scn; + } + } + seterr(ERROR_NOSUCHSCN); + } + return NULL; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/nlist.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/nlist.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,253 @@ +/* + * nlist.c - implementation of the nlist(3) function. + * Copyright (C) 1995 - 2004 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: nlist.c,v 1.14 2006/08/18 00:01:07 michael Exp $"; +#endif /* lint */ + +#if !defined(_WIN32) +#if HAVE_FCNTL_H +#include +#else +extern int open(); +#endif /* HAVE_FCNTL_H */ +#endif /* defined(_WIN32) */ + +#ifndef O_RDONLY +#define O_RDONLY 0 +#endif /* O_RDONLY */ + +#ifndef O_BINARY +#define O_BINARY 0 +#endif /* O_BINARY */ + +#define FILE_OPEN_MODE (O_RDONLY | O_BINARY) + +#define PRIME 217 + +struct hash { + const char* name; + unsigned long hash; + unsigned next; +}; + +static const char* +symbol_name(Elf *elf, const void *syms, const char *names, size_t nlimit, size_t index) { + size_t off; + + if (elf->e_class == ELFCLASS32) { + off = ((Elf32_Sym*)syms)[index].st_name; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + off = ((Elf64_Sym*)syms)[index].st_name; + } +#endif /* __LIBELF64 */ + else { + return NULL; + } + if (off >= 0 && off < nlimit) { + return &names[off]; + } + return NULL; +} + +static void +copy_symbol(Elf *elf, struct nlist *np, const void *syms, size_t index) { + if (elf->e_class == ELFCLASS32) { + np->n_value = ((Elf32_Sym*)syms)[index].st_value; + np->n_scnum = ((Elf32_Sym*)syms)[index].st_shndx; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + np->n_value = ((Elf64_Sym*)syms)[index].st_value; + np->n_scnum = ((Elf64_Sym*)syms)[index].st_shndx; + } +#endif /* __LIBELF64 */ + /* + * this needs more work + */ + np->n_type = 0; + np->n_sclass = 0; + np->n_numaux = 0; +} + +static int +_elf_nlist(Elf *elf, struct nlist *nl) { + unsigned first[PRIME]; + Elf_Scn *symtab = NULL; + Elf_Scn *strtab = NULL; + Elf_Data *symdata; + Elf_Data *strdata; + size_t symsize; + size_t nsymbols; + const char *name; + struct hash *table; + unsigned long hash; + unsigned i; + struct nlist *np; + + /* + * Get and translate ELF header, section table and so on. + * Must be class independent, so don't use elf32_get*(). + */ + if (elf->e_kind != ELF_K_ELF) { + return -1; + } + if (!elf->e_ehdr && !_elf_cook(elf)) { + return -1; + } + + /* + * Find symbol table. If there is none, try dynamic symbols. + */ + for (symtab = elf->e_scn_1; symtab; symtab = symtab->s_link) { + if (symtab->s_type == SHT_SYMTAB) { + break; + } + if (symtab->s_type == SHT_DYNSYM) { + strtab = symtab; + } + } + if (!symtab && !(symtab = strtab)) { + return -1; + } + + /* + * Get associated string table. + */ + i = 0; + if (elf->e_class == ELFCLASS32) { + i = symtab->s_shdr32.sh_link; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + i = symtab->s_shdr64.sh_link; + } +#endif /* __LIBELF64 */ + if (i == 0) { + return -1; + } + for (strtab = elf->e_scn_1; strtab; strtab = strtab->s_link) { + if (strtab->s_index == i) { + break; + } + } + if (!strtab || strtab->s_type != SHT_STRTAB) { + return -1; + } + + /* + * Get and translate section data. + */ + symdata = elf_getdata(symtab, NULL); + strdata = elf_getdata(strtab, NULL); + if (!symdata || !strdata) { + return -1; + } + symsize = _msize(elf->e_class, _elf_version, ELF_T_SYM); + elf_assert(symsize); + nsymbols = symdata->d_size / symsize; + if (!symdata->d_buf || !strdata->d_buf || !nsymbols || !strdata->d_size) { + return -1; + } + + /* + * Build a simple hash table. + */ + if (!(table = (struct hash*)malloc(nsymbols * sizeof(*table)))) { + return -1; + } + for (i = 0; i < PRIME; i++) { + first[i] = 0; + } + for (i = 0; i < nsymbols; i++) { + table[i].name = NULL; + table[i].hash = 0; + table[i].next = 0; + } + for (i = 1; i < nsymbols; i++) { + name = symbol_name(elf, symdata->d_buf, strdata->d_buf, + strdata->d_size, i); + if (name == NULL) { + free(table); + return -1; + } + if (*name != '\0') { + table[i].name = name; + table[i].hash = elf_hash((unsigned char*)name); + hash = table[i].hash % PRIME; + table[i].next = first[hash]; + first[hash] = i; + } + } + + /* + * Lookup symbols, one by one. + */ + for (np = nl; (name = np->n_name) && *name; np++) { + hash = elf_hash((unsigned char*)name); + for (i = first[hash % PRIME]; i; i = table[i].next) { + if (table[i].hash == hash && !strcmp(table[i].name, name)) { + break; + } + } + if (i) { + copy_symbol(elf, np, symdata->d_buf, i); + } + else { + np->n_value = 0; + np->n_scnum = 0; + np->n_type = 0; + np->n_sclass = 0; + np->n_numaux = 0; + } + } + free(table); + return 0; +} + +int +nlist(const char *filename, struct nlist *nl) { + int result = -1; + unsigned oldver; + Elf *elf; + int fd; + + if ((oldver = elf_version(EV_CURRENT)) != EV_NONE) { + if ((fd = open(filename, FILE_OPEN_MODE)) != -1) { + if ((elf = elf_begin(fd, ELF_C_READ, NULL))) { + result = _elf_nlist(elf, nl); + elf_end(elf); + } + close(fd); + } + elf_version(oldver); + } + if (result) { + while (nl->n_name && *nl->n_name) { + nl->n_value = 0; + nl++; + } + } + return result; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/nlist.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/nlist.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,48 @@ +/* + * nlist.h - public header file for nlist(3). + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* @(#) $Id: nlist.h,v 1.9 2006/04/25 16:26:39 michael Exp $ */ + +#ifndef _NLIST_H +#define _NLIST_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct nlist { + char* n_name; + long n_value; + short n_scnum; + unsigned short n_type; + char n_sclass; + char n_numaux; +}; + +#if (__STDC__ + 0) || defined(__cplusplus) || defined(_WIN32) +extern int nlist(const char *__filename, struct nlist *__nl); +#else /* __STDC__ || defined(__cplusplus) */ +extern int nlist(); +#endif /* __STDC__ || defined(__cplusplus) */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _NLIST_H */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/opt.delscn.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/opt.delscn.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,205 @@ +/* +opt.delscn.c - implementation of the elf_delscn(3) function. +Copyright (C) 1995 - 2001 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: opt.delscn.c,v 1.11 2005/05/21 15:39:25 michael Exp $"; +#endif /* lint */ + +static size_t +_newindex(size_t old, size_t index) { + return old == index ? SHN_UNDEF : (old > index ? old - 1 : old); +} + +static void +_elf32_update_shdr(Elf *elf, size_t index) { + Elf32_Shdr *shdr; + Elf_Scn *scn; + + ((Elf32_Ehdr*)elf->e_ehdr)->e_shnum = elf->e_scn_n->s_index + 1; + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + shdr = &scn->s_shdr32; + switch (shdr->sh_type) { + case SHT_REL: + case SHT_RELA: + shdr->sh_info = _newindex(shdr->sh_info, index); + /* fall through */ + case SHT_DYNSYM: + case SHT_DYNAMIC: + case SHT_HASH: + case SHT_SYMTAB: +#if __LIBELF_SYMBOL_VERSIONS +#if __LIBELF_SUN_SYMBOL_VERSIONS + case SHT_SUNW_verdef: + case SHT_SUNW_verneed: + case SHT_SUNW_versym: +#else /* __LIBELF_SUN_SYMBOL_VERSIONS */ + case SHT_GNU_verdef: + case SHT_GNU_verneed: + case SHT_GNU_versym: +#endif /* __LIBELF_SUN_SYMBOL_VERSIONS */ +#endif /* __LIBELF_SYMBOL_VERSIONS */ + shdr->sh_link = _newindex(shdr->sh_link, index); + /* fall through */ + default: + break; + } + } +} + +#if __LIBELF64 + +static void +_elf64_update_shdr(Elf *elf, size_t index) { + Elf64_Shdr *shdr; + Elf_Scn *scn; + + ((Elf64_Ehdr*)elf->e_ehdr)->e_shnum = elf->e_scn_n->s_index + 1; + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + shdr = &scn->s_shdr64; + switch (shdr->sh_type) { + case SHT_REL: + case SHT_RELA: + shdr->sh_info = _newindex(shdr->sh_info, index); + /* fall through */ + case SHT_DYNSYM: + case SHT_DYNAMIC: + case SHT_HASH: + case SHT_SYMTAB: +#if __LIBELF_SYMBOL_VERSIONS +#if __LIBELF_SUN_SYMBOL_VERSIONS + case SHT_SUNW_verdef: + case SHT_SUNW_verneed: + case SHT_SUNW_versym: +#else /* __LIBELF_SUN_SYMBOL_VERSIONS */ + case SHT_GNU_verdef: + case SHT_GNU_verneed: + case SHT_GNU_versym: +#endif /* __LIBELF_SUN_SYMBOL_VERSIONS */ +#endif /* __LIBELF_SYMBOL_VERSIONS */ + shdr->sh_link = _newindex(shdr->sh_link, index); + /* fall through */ + default: + break; + } + } +} + +#endif /* __LIBELF64 */ + +size_t +elf_delscn(Elf *elf, Elf_Scn *scn) { + Elf_Scn *pscn; + Scn_Data *sd; + Scn_Data *tmp; + size_t index; + + if (!elf || !scn) { + return SHN_UNDEF; + } + elf_assert(elf->e_magic == ELF_MAGIC); + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(elf->e_ehdr); + if (scn->s_elf != elf) { + seterr(ERROR_ELFSCNMISMATCH); + return SHN_UNDEF; + } + elf_assert(elf->e_scn_1); + if (scn == elf->e_scn_1) { + seterr(ERROR_NULLSCN); + return SHN_UNDEF; + } + + /* + * Find previous section. + */ + for (pscn = elf->e_scn_1; pscn->s_link; pscn = pscn->s_link) { + if (pscn->s_link == scn) { + break; + } + } + if (pscn->s_link != scn) { + seterr(ERROR_ELFSCNMISMATCH); + return SHN_UNDEF; + } + /* + * Unlink section. + */ + if (elf->e_scn_n == scn) { + elf->e_scn_n = pscn; + } + pscn->s_link = scn->s_link; + index = scn->s_index; + /* + * Free section descriptor and data. + */ + for (sd = scn->s_data_1; sd; sd = tmp) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + tmp = sd->sd_link; + if (sd->sd_free_data && sd->sd_memdata) { + free(sd->sd_memdata); + } + if (sd->sd_freeme) { + free(sd); + } + } + if ((sd = scn->s_rawdata)) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + if (sd->sd_free_data && sd->sd_memdata) { + free(sd->sd_memdata); + } + if (sd->sd_freeme) { + free(sd); + } + } + if (scn->s_freeme) { + elf_assert(scn->s_index > 0); + free(scn); + } + /* + * Adjust section indices. + */ + for (scn = pscn->s_link; scn; scn = scn->s_link) { + elf_assert(scn->s_index > index); + scn->s_index--; + } + /* + * Adjust ELF header and well-known section headers. + */ + if (elf->e_class == ELFCLASS32) { + _elf32_update_shdr(elf, index); + return index; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + _elf64_update_shdr(elf, index); + return index; + } +#endif /* __LIBELF64 */ + else if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return SHN_UNDEF; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/private.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/private.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,425 @@ +/* + * private.h - private definitions for libelf. + * Copyright (C) 1995 - 2007 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* @(#) $Id: private.h,v 1.38 2007/09/07 12:07:59 michael Exp $ */ + +#ifndef _PRIVATE_H +#define _PRIVATE_H + +#define __LIBELF_INTERNAL__ 1 + +#if HAVE_CONFIG_H +# include +#endif /* HAVE_CONFIG_H */ + +/* + * Workaround for GLIBC bug: + * include before + */ +#if HAVE_STDINT_H +#include +#endif +#include + +#if STDC_HEADERS +# include +# include +#else /* STDC_HEADERS */ +extern void *malloc(), *realloc(); +extern void free(), bcopy(), abort(); +extern int strcmp(), strncmp(), memcmp(); +extern void *memcpy(), *memmove(), *memset(); +#endif /* STDC_HEADERS */ + +#if defined(_WIN32) +#include +#else +#if HAVE_UNISTD_H +# include +#else /* HAVE_UNISTD_H */ +extern int read(), write(), close(); +extern off_t lseek(); +#if HAVE_FTRUNCATE +extern int ftruncate(); +#endif /* HAVE_FTRUNCATE */ +#endif /* HAVE_UNISTD_H */ +#endif /* defined(_WIN32) */ + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif /* SEEK_SET */ +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif /* SEEK_CUR */ +#ifndef SEEK_END +#define SEEK_END 2 +#endif /* SEEK_END */ + +#if !HAVE_MEMCMP +# define memcmp strncmp +#endif /* !HAVE_MEMCMP */ +#if !HAVE_MEMCPY +# define memcpy(d,s,n) bcopy(s,d,n) +#endif /* !HAVE_MEMCPY */ +#if !HAVE_MEMMOVE +# define memmove(d,s,n) bcopy(s,d,n) +#endif /* !HAVE_MEMMOVE */ + +#if !HAVE_MEMSET +# define memset _elf_memset +extern void *_elf_memset(); +#endif /* !HAVE_MEMSET */ + +#if HAVE_STRUCT_NLIST_DECLARATION +# define nlist __override_nlist_declaration +#endif /* HAVE_STRUCT_NLIST_DECLARATION */ + +#if __LIBELF_NEED_LINK_H +# include +#elif __LIBELF_NEED_SYS_LINK_H +# include +#endif /* __LIBELF_NEED_LINK_H */ + +#include + +#if HAVE_STRUCT_NLIST_DECLARATION +# undef nlist +#endif /* HAVE_STRUCT_NLIST_DECLARATION */ + +#if __LIBELF64 +#include +#endif /* __LIBELF64 */ + +typedef struct Scn_Data Scn_Data; + +/* + * ELF descriptor + */ +struct Elf { + /* common */ + size_t e_size; /* file/member size */ + size_t e_dsize; /* size of memory image */ + Elf_Kind e_kind; /* kind of file */ + char* e_data; /* file/member data */ + char* e_rawdata; /* file/member raw data */ + size_t e_idlen; /* identifier size */ + int e_fd; /* file descriptor */ + unsigned e_count; /* activation count */ + /* archive members (still common) */ + Elf* e_parent; /* NULL if not an archive member */ + size_t e_next; /* 0 if not an archive member */ + size_t e_base; /* 0 if not an archive member */ + Elf* e_link; /* next archive member or NULL */ + Elf_Arhdr* e_arhdr; /* archive member header or NULL */ + /* archives */ + size_t e_off; /* current member offset (for elf_begin) */ + Elf* e_members; /* linked list of active archive members */ + char* e_symtab; /* archive symbol table */ + size_t e_symlen; /* length of archive symbol table */ + char* e_strtab; /* archive string table */ + size_t e_strlen; /* length of archive string table */ + /* ELF files */ + unsigned e_class; /* ELF class */ + unsigned e_encoding; /* ELF data encoding */ + unsigned e_version; /* ELF version */ + char* e_ehdr; /* ELF header */ + char* e_phdr; /* ELF program header table */ + size_t e_phnum; /* size of program header table */ + Elf_Scn* e_scn_1; /* first section */ + Elf_Scn* e_scn_n; /* last section */ + unsigned e_elf_flags; /* elf flags (ELF_F_*) */ + unsigned e_ehdr_flags; /* ehdr flags (ELF_F_*) */ + unsigned e_phdr_flags; /* phdr flags (ELF_F_*) */ + /* misc flags */ + unsigned e_readable : 1; /* file is readable */ + unsigned e_writable : 1; /* file is writable */ + unsigned e_disabled : 1; /* e_fd has been disabled */ + unsigned e_cooked : 1; /* e_data was modified */ + unsigned e_free_syms : 1; /* e_symtab is malloc'ed */ + unsigned e_unmap_data : 1; /* e_data is mmap'ed */ + unsigned e_memory : 1; /* created by elf_memory() */ + /* magic number for debugging */ + long e_magic; +}; + +#define ELF_MAGIC 0x012b649e + +#define INIT_ELF {\ + /* e_size */ 0,\ + /* e_dsize */ 0,\ + /* e_kind */ ELF_K_NONE,\ + /* e_data */ NULL,\ + /* e_rawdata */ NULL,\ + /* e_idlen */ 0,\ + /* e_fd */ -1,\ + /* e_count */ 1,\ + /* e_parent */ NULL,\ + /* e_next */ 0,\ + /* e_base */ 0,\ + /* e_link */ NULL,\ + /* e_arhdr */ NULL,\ + /* e_off */ 0,\ + /* e_members */ NULL,\ + /* e_symtab */ NULL,\ + /* e_symlen */ 0,\ + /* e_strtab */ NULL,\ + /* e_strlen */ 0,\ + /* e_class */ ELFCLASSNONE,\ + /* e_encoding */ ELFDATANONE,\ + /* e_version */ EV_NONE,\ + /* e_ehdr */ NULL,\ + /* e_phdr */ NULL,\ + /* e_phnum */ 0,\ + /* e_scn_1 */ NULL,\ + /* e_scn_n */ NULL,\ + /* e_elf_flags */ 0,\ + /* e_ehdr_flags */ 0,\ + /* e_phdr_flags */ 0,\ + /* e_readable */ 0,\ + /* e_writable */ 0,\ + /* e_disabled */ 0,\ + /* e_cooked */ 0,\ + /* e_free_syms */ 0,\ + /* e_unmap_data */ 0,\ + /* e_memory */ 0,\ + /* e_magic */ ELF_MAGIC\ +} + +/* + * Section descriptor + */ +struct Elf_Scn { + Elf_Scn* s_link; /* pointer to next Elf_Scn */ + Elf* s_elf; /* pointer to elf descriptor */ + size_t s_index; /* number of this section */ + unsigned s_scn_flags; /* section flags (ELF_F_*) */ + unsigned s_shdr_flags; /* shdr flags (ELF_F_*) */ + Scn_Data* s_data_1; /* first data buffer */ + Scn_Data* s_data_n; /* last data buffer */ + Scn_Data* s_rawdata; /* raw data buffer */ + /* data copied from shdr */ + unsigned s_type; /* section type */ + size_t s_offset; /* section offset */ + size_t s_size; /* section size */ + /* misc flags */ + unsigned s_freeme : 1; /* this Elf_Scn was malloc'ed */ + /* section header */ + union { +#if __LIBELF64 + Elf64_Shdr u_shdr64; +#endif /* __LIBELF64 */ + Elf32_Shdr u_shdr32; + } s_uhdr; + /* magic number for debugging */ + long s_magic; +}; +#define s_shdr32 s_uhdr.u_shdr32 +#define s_shdr64 s_uhdr.u_shdr64 + +#define SCN_MAGIC 0x012c747d + +#define INIT_SCN {\ + /* s_link */ NULL,\ + /* s_elf */ NULL,\ + /* s_index */ 0,\ + /* s_scn_flags */ 0,\ + /* s_shdr_flags */ 0,\ + /* s_data_1 */ NULL,\ + /* s_data_n */ NULL,\ + /* s_rawdata */ NULL,\ + /* s_type */ SHT_NULL,\ + /* s_offset */ 0,\ + /* s_size */ 0,\ + /* s_freeme */ 0,\ + /* s_uhdr */ {{0,}},\ + /* s_magic */ SCN_MAGIC\ +} + +/* + * Data descriptor + */ +struct Scn_Data { + Elf_Data sd_data; /* must be first! */ + Scn_Data* sd_link; /* pointer to next Scn_Data */ + Elf_Scn* sd_scn; /* pointer to section */ + char* sd_memdata; /* memory image of section */ + unsigned sd_data_flags; /* data flags (ELF_F_*) */ + /* misc flags */ + unsigned sd_freeme : 1; /* this Scn_Data was malloc'ed */ + unsigned sd_free_data : 1; /* sd_memdata is malloc'ed */ + /* magic number for debugging */ + long sd_magic; +}; + +#define DATA_MAGIC 0x01072639 + +#define INIT_DATA {\ + {\ + /* d_buf */ NULL,\ + /* d_type */ ELF_T_BYTE,\ + /* d_size */ 0,\ + /* d_off */ 0,\ + /* d_align */ 0,\ + /* d_version */ EV_NONE\ + },\ + /* sd_link */ NULL,\ + /* sd_scn */ NULL,\ + /* sd_memdata */ NULL,\ + /* sd_data_flags */ 0,\ + /* sd_freeme */ 0,\ + /* sd_free_data */ 0,\ + /* sd_magic */ DATA_MAGIC\ +} + +/* + * Private status variables + */ +extern unsigned _elf_version; +extern int _elf_errno; +extern int _elf_fill; +extern int _elf_sanity_checks; +#define SANITY_CHECK_STRPTR (1u << 0) + +/* + * Private functions + */ +extern void *_elf_read __P((Elf*, void*, size_t, size_t)); +extern void *_elf_mmap __P((Elf*)); +extern int _elf_cook __P((Elf*)); +extern char *_elf_getehdr __P((Elf*, unsigned)); +extern char *_elf_getphdr __P((Elf*, unsigned)); +extern Elf_Data *_elf_xlatetom __P((const Elf*, Elf_Data*, const Elf_Data*)); +extern Elf_Type _elf_scn_type __P((unsigned)); +extern size_t _elf32_xltsize __P((const Elf_Data *__src, unsigned __dv, unsigned __encode, int __tof)); +extern size_t _elf64_xltsize __P((const Elf_Data *__src, unsigned __dv, unsigned __encode, int __tof)); +extern int _elf_update_shnum(Elf *__elf, size_t __shnum); +extern Elf_Scn *_elf_first_scn(Elf *__elf); + +/* + * Special translators + */ +extern size_t _elf_verdef_32L11_tof __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verdef_32L11_tom __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verdef_32M11_tof __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verdef_32M11_tom __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verdef_64L11_tof __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verdef_64L11_tom __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verdef_64M11_tof __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verdef_64M11_tom __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verneed_32L11_tof __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verneed_32L11_tom __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verneed_32M11_tof __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verneed_32M11_tom __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verneed_64L11_tof __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verneed_64L11_tom __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verneed_64M11_tof __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verneed_64M11_tom __P((unsigned char *dst, const unsigned char *src, size_t n)); + +/* + * Private data + */ +extern const Elf_Scn _elf_scn_init; +extern const Scn_Data _elf_data_init; +extern const size_t _elf_fmsize[2][EV_CURRENT - EV_NONE][ELF_T_NUM][2]; + +/* + * Access macros for _elf_fmsize[] + */ +#define _fmsize(c,v,t,w) \ + (_elf_fmsize[(c)-ELFCLASS32][(v)-EV_NONE-1][(t)-ELF_T_BYTE][(w)]) +#define _fsize(c,v,t) _fmsize((c),(v),(t),1) +#define _msize(c,v,t) _fmsize((c),(v),(t),0) + +/* + * Various checks + */ +#define valid_class(c) ((c) >= ELFCLASS32 && (c) <= ELFCLASS64) +#define valid_encoding(e) ((e) >= ELFDATA2LSB && (e) <= ELFDATA2MSB) +#define valid_version(v) ((v) > EV_NONE && (v) <= EV_CURRENT) +#define valid_type(t) ((unsigned)(t) < ELF_T_NUM) + +/* + * Error codes + */ +enum { +#define __err__(a,b) a, +#include /* include constants from errors.h */ +#undef __err__ +ERROR_NUM +}; + +#define seterr(err) (_elf_errno = (err)) + +/* + * Sizes of data types (external representation) + * These definitions should be in , but... + */ +#ifndef ELF32_FSZ_ADDR +# define ELF32_FSZ_ADDR 4 +# define ELF32_FSZ_HALF 2 +# define ELF32_FSZ_OFF 4 +# define ELF32_FSZ_SWORD 4 +# define ELF32_FSZ_WORD 4 +#endif /* ELF32_FSZ_ADDR */ +#ifndef ELF64_FSZ_ADDR +# define ELF64_FSZ_ADDR 8 +# define ELF64_FSZ_HALF 2 +# define ELF64_FSZ_OFF 8 +# define ELF64_FSZ_SWORD 4 +# define ELF64_FSZ_SXWORD 8 +# define ELF64_FSZ_WORD 4 +# define ELF64_FSZ_XWORD 8 +#endif /* ELF64_FSZ_ADDR */ + +/* + * More missing pieces, in no particular order + */ +#ifndef SHT_SYMTAB_SHNDX +#define SHT_SYMTAB_SHNDX 18 +#endif /* SHT_SYMTAB_SHNDX */ + +#ifndef SHN_XINDEX +#define SHN_XINDEX 0xffff +#endif /* SHN_XINDEX */ + +#ifndef PN_XNUM +#define PN_XNUM 0xffff +#endif /* PN_XNUM */ + +/* + * Debugging + */ +#if ENABLE_DEBUG +extern void __elf_assert __P((const char*, unsigned, const char*)); +# if (__STDC__ + 0) +# define elf_assert(x) do{if(!(x))__elf_assert(__FILE__,__LINE__,#x);}while(0) +# else /* __STDC__ */ +# define elf_assert(x) do{if(!(x))__elf_assert(__FILE__,__LINE__,"x");}while(0) +# endif /* __STDC__ */ +#else /* ENABLE_DEBUG */ +# define elf_assert(x) do{}while(0) +#endif /* ENABLE_DEBUG */ + +/* + * Return values for certain functions + */ +#define LIBELF_SUCCESS 1 +#define LIBELF_FAILURE 0 + +#endif /* _PRIVATE_H */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/rand.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/rand.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,43 @@ +/* +rand.c - implementation of the elf_rand(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: rand.c,v 1.6 2005/05/21 15:39:25 michael Exp $"; +#endif /* lint */ + +size_t +elf_rand(Elf *elf, size_t offset) { + if (!elf) { + return 0; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_AR) { + seterr(ERROR_NOTARCHIVE); + } + else if (offset <= 0 || offset > elf->e_size) { + seterr(ERROR_BADOFF); + } + else { + elf->e_off = offset; + return offset; + } + return 0; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/rawdata.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/rawdata.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,89 @@ +/* +rawdata.c - implementation of the elf_rawdata(3) function. +Copyright (C) 1995 - 2000 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: rawdata.c,v 1.9 2005/05/21 15:39:26 michael Exp $"; +#endif /* lint */ + +Elf_Data* +elf_rawdata(Elf_Scn *scn, Elf_Data *data) { + Scn_Data *sd; + Elf *elf; + + if (!scn) { + return NULL; + } + elf_assert(scn->s_magic == SCN_MAGIC); + elf = scn->s_elf; + elf_assert(elf); + elf_assert(elf->e_magic == ELF_MAGIC); + if (!elf->e_readable) { + return NULL; + } + else if (scn->s_index == SHN_UNDEF || scn->s_type == SHT_NULL) { + seterr(ERROR_NULLSCN); + } + else if (data) { + return NULL; + } + else if ((sd = scn->s_rawdata)) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + return &sd->sd_data; + } + else if (scn->s_offset < 0 || scn->s_offset > elf->e_size) { + seterr(ERROR_OUTSIDE); + } + else if (scn->s_type != SHT_NOBITS + && scn->s_offset + scn->s_size > elf->e_size) { + seterr(ERROR_TRUNC_SCN); + } + else if (!(sd = (Scn_Data*)malloc(sizeof(*sd)))) { + seterr(ERROR_MEM_SCNDATA); + } + else { + *sd = _elf_data_init; + sd->sd_scn = scn; + sd->sd_freeme = 1; + sd->sd_data.d_size = scn->s_size; + sd->sd_data.d_version = _elf_version; + if (scn->s_type != SHT_NOBITS && scn->s_size) { + if (!(sd->sd_memdata = (char*)malloc(scn->s_size))) { + seterr(ERROR_IO_2BIG); + free(sd); + return NULL; + } + else if (elf->e_rawdata) { + memcpy(sd->sd_memdata, elf->e_rawdata + scn->s_offset, scn->s_size); + } + else if (!_elf_read(elf, sd->sd_memdata, scn->s_offset, scn->s_size)) { + free(sd->sd_memdata); + free(sd); + return NULL; + } + sd->sd_data.d_buf = sd->sd_memdata; + sd->sd_free_data = 1; + } + scn->s_rawdata = sd; + return &sd->sd_data; + } + return NULL; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/rawfile.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/rawfile.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,52 @@ +/* +rawfile.c - implementation of the elf_rawfile(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: rawfile.c,v 1.6 2005/05/21 15:39:26 michael Exp $"; +#endif /* lint */ + +char* +elf_rawfile(Elf *elf, size_t *ptr) { + size_t tmp; + + if (!ptr) { + ptr = &tmp; + } + *ptr = 0; + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (!elf->e_readable) { + return NULL; + } + else if (elf->e_size && !elf->e_rawdata) { + elf_assert(elf->e_data); + if (!elf->e_cooked) { + elf->e_rawdata = elf->e_data; + } + else if (!(elf->e_rawdata = _elf_read(elf, NULL, 0, elf->e_size))) { + return NULL; + } + *ptr = elf->e_size; + } + return elf->e_rawdata; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/strptr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/strptr.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,150 @@ +/* + * strptr.c - implementation of the elf_strptr(3) function. + * Copyright (C) 1995 - 2007 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: strptr.c,v 1.11 2007/09/07 12:07:59 michael Exp $"; +#endif /* lint */ + +char* +elf_strptr(Elf *elf, size_t section, size_t offset) { + Elf_Data *data; + Elf_Scn *scn; + size_t n; + char *s; + + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (!(scn = elf_getscn(elf, section))) { + return NULL; + } + if (scn->s_index == SHN_UNDEF) { + seterr(ERROR_NOSTRTAB); + return NULL; + } + /* + * checking the section header is more appropriate + */ + if (elf->e_class == ELFCLASS32) { + if (scn->s_shdr32.sh_type != SHT_STRTAB) { + seterr(ERROR_NOSTRTAB); + return NULL; + } + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + if (scn->s_shdr64.sh_type != SHT_STRTAB) { + seterr(ERROR_NOSTRTAB); + return NULL; + } + } +#endif /* __LIBELF64 */ + else if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + return NULL; + } + else { + seterr(ERROR_UNKNOWN_CLASS); + return NULL; + } + /* + * Find matching buffer + */ + n = 0; + data = NULL; + if (elf->e_elf_flags & ELF_F_LAYOUT) { + /* + * Programmer is responsible for d_off + * Note: buffers may be in any order! + */ + while ((data = elf_getdata(scn, data))) { + n = data->d_off; + if (offset >= n && offset - n < data->d_size) { + /* + * Found it + */ + break; + } + } + } + else { + /* + * Calculate offsets myself + */ + while ((data = elf_getdata(scn, data))) { + if (data->d_align > 1) { + n += data->d_align - 1; + n -= n % data->d_align; + } + if (offset < n) { + /* + * Invalid offset: points into a hole + */ + seterr(ERROR_BADSTROFF); + return NULL; + } + if (offset - n < data->d_size) { + /* + * Found it + */ + break; + } + n += data->d_size; + } + } + if (data == NULL) { + /* + * Not found + */ + seterr(ERROR_BADSTROFF); + return NULL; + } + if (data->d_buf == NULL) { + /* + * Buffer is NULL (usually the programmers' fault) + */ + seterr(ERROR_NULLBUF); + return NULL; + } + offset -= n; + s = (char*)data->d_buf; + if (!(_elf_sanity_checks & SANITY_CHECK_STRPTR)) { + return s + offset; + } + /* + * Perform extra sanity check + */ + for (n = offset; n < data->d_size; n++) { + if (s[n] == '\0') { + /* + * Return properly NUL terminated string + */ + return s + offset; + } + } + /* + * String is not NUL terminated + * Return error to avoid SEGV in application + */ + seterr(ERROR_UNTERM); + return NULL; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/swap64.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/swap64.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,81 @@ +/* +swap64.c - 64-bit byte swapping functions. +Copyright (C) 1995 - 2001 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include + +#if __LIBELF64 + +#ifndef lint +static const char rcsid[] = "@(#) $Id: swap64.c,v 1.5 2005/05/21 15:39:26 michael Exp $"; +#endif /* lint */ + +__libelf_u64_t +_elf_load_u64L(const unsigned char *from) { + return ((__libelf_u64_t)__load_u32L(from + 4) << 32) + | (__libelf_u64_t)__load_u32L(from); +} + +__libelf_u64_t +_elf_load_u64M(const unsigned char *from) { + return ((__libelf_u64_t)__load_u32M(from) << 32) + | (__libelf_u64_t)__load_u32M(from + 4); +} + +__libelf_i64_t +_elf_load_i64L(const unsigned char *from) { + return ((__libelf_i64_t)__load_i32L(from + 4) << 32) + | (__libelf_u64_t)__load_u32L(from); +} + +__libelf_i64_t +_elf_load_i64M(const unsigned char *from) { + return ((__libelf_i64_t)__load_i32M(from) << 32) + | (__libelf_u64_t)__load_u32M(from + 4); +} + +void +_elf_store_u64L(unsigned char *to, __libelf_u64_t v) { + __store_u32L(to, (__libelf_u32_t)v); + v >>= 32; + __store_u32L(to + 4, (__libelf_u32_t)v); +} + +void +_elf_store_u64M(unsigned char *to, __libelf_u64_t v) { + __store_u32M(to + 4, (__libelf_u32_t)v); + v >>= 32; + __store_u32M(to, (__libelf_u32_t)v); +} + +void +_elf_store_i64L(unsigned char *to, __libelf_u64_t v) { + __store_u32L(to, (__libelf_u32_t)v); + v >>= 32; + __store_i32L(to + 4, (__libelf_u32_t)v); +} + +void +_elf_store_i64M(unsigned char *to, __libelf_u64_t v) { + __store_u32M(to + 4, (__libelf_u32_t)v); + v >>= 32; + __store_i32M(to, (__libelf_u32_t)v); +} + +#endif /* __LIBELF64 */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/sys_elf.h.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/sys_elf.h.in Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,130 @@ +/* +sys_elf.h.in - configure template for private "switch" file. +Copyright (C) 1998 - 2001 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* @(#) $Id: sys_elf.h.in,v 1.12 2006/09/07 15:55:42 michael Exp $ */ + +/* + * DO NOT USE THIS IN APPLICATIONS - #include INSTEAD! + */ + +/* Define to `' or `' if one of them is present */ +#undef __LIBELF_HEADER_ELF_H + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_LINK_H + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_SYS_LINK_H + +/* Define if you want 64-bit support (and your system supports it) */ +#undef __LIBELF64 + +/* Define if you want 64-bit support, and are running IRIX */ +#undef __LIBELF64_IRIX + +/* Define if you want 64-bit support, and are running Linux */ +#undef __LIBELF64_LINUX + +/* Define if you want symbol versioning (and your system supports it) */ +#undef __LIBELF_SYMBOL_VERSIONS + +/* Define to a 64-bit signed integer type if one exists */ +#undef __libelf_i64_t + +/* Define to a 64-bit unsigned integer type if one exists */ +#undef __libelf_u64_t + +/* Define to a 32-bit signed integer type if one exists */ +#undef __libelf_i32_t + +/* Define to a 32-bit unsigned integer type if one exists */ +#undef __libelf_u32_t + +/* Define to a 16-bit signed integer type if one exists */ +#undef __libelf_i16_t + +/* Define to a 16-bit unsigned integer type if one exists */ +#undef __libelf_u16_t + +/* + * Ok, now get the correct instance of elf.h... + */ +#ifdef __LIBELF_HEADER_ELF_H +# include __LIBELF_HEADER_ELF_H +#else /* __LIBELF_HEADER_ELF_H */ +# if __LIBELF_INTERNAL__ +# include +# else /* __LIBELF_INTERNAL__ */ +# include +# endif /* __LIBELF_INTERNAL__ */ +#endif /* __LIBELF_HEADER_ELF_H */ + +/* + * On some systems, is severely broken. Try to fix it. + */ +#ifdef __LIBELF_HEADER_ELF_H + +# ifndef ELF32_FSZ_ADDR +# define ELF32_FSZ_ADDR 4 +# define ELF32_FSZ_HALF 2 +# define ELF32_FSZ_OFF 4 +# define ELF32_FSZ_SWORD 4 +# define ELF32_FSZ_WORD 4 +# endif /* ELF32_FSZ_ADDR */ + +# ifndef STN_UNDEF +# define STN_UNDEF 0 +# endif /* STN_UNDEF */ + +# if __LIBELF64 + +# ifndef ELF64_FSZ_ADDR +# define ELF64_FSZ_ADDR 8 +# define ELF64_FSZ_HALF 2 +# define ELF64_FSZ_OFF 8 +# define ELF64_FSZ_SWORD 4 +# define ELF64_FSZ_WORD 4 +# define ELF64_FSZ_SXWORD 8 +# define ELF64_FSZ_XWORD 8 +# endif /* ELF64_FSZ_ADDR */ + +# ifndef ELF64_ST_BIND +# define ELF64_ST_BIND(i) ((i)>>4) +# define ELF64_ST_TYPE(i) ((i)&0xf) +# define ELF64_ST_INFO(b,t) (((b)<<4)+((t)&0xf)) +# endif /* ELF64_ST_BIND */ + +# ifndef ELF64_R_SYM +# define ELF64_R_SYM(i) ((Elf64_Xword)(i)>>32) +# define ELF64_R_TYPE(i) ((i)&0xffffffffL) +# define ELF64_R_INFO(s,t) (((Elf64_Xword)(s)<<32)+((t)&0xffffffffL)) +# endif /* ELF64_R_SYM */ + +# if __LIBELF64_LINUX +typedef __libelf_u64_t Elf64_Addr; +typedef __libelf_u16_t Elf64_Half; +typedef __libelf_u64_t Elf64_Off; +typedef __libelf_i32_t Elf64_Sword; +typedef __libelf_u32_t Elf64_Word; +typedef __libelf_i64_t Elf64_Sxword; +typedef __libelf_u64_t Elf64_Xword; +# endif /* __LIBELF64_LINUX */ + +# endif /* __LIBELF64 */ +#endif /* __LIBELF_HEADER_ELF_H */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/sys_elf.h.w32 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/sys_elf.h.w32 Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,130 @@ +/* + * lib/sys_elf.h.w32 - internal configuration file for W32 port + * Copyright (C) 2004 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @(#) $Id: sys_elf.h.w32,v 1.2 2006/09/07 15:55:42 michael Exp $ + */ + +/* + * DO NOT USE THIS IN APPLICATIONS - #include INSTEAD! + */ + +/* Define to `' or `' if one of them is present */ +#undef __LIBELF_HEADER_ELF_H + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_LINK_H + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_SYS_LINK_H + +/* Define if you want 64-bit support (and your system supports it) */ +#define __LIBELF64 1 + +/* Define if you want 64-bit support, and are running IRIX */ +#undef __LIBELF64_IRIX + +/* Define if you want 64-bit support, and are running Linux */ +#undef __LIBELF64_LINUX + +/* Define if you want symbol versioning (and your system supports it) */ +#define __LIBELF_SYMBOL_VERSIONS 1 + +/* Define to a 64-bit signed integer type if one exists */ +#define __libelf_i64_t __int64 + +/* Define to a 64-bit unsigned integer type if one exists */ +#define __libelf_u64_t unsigned __int64 + +/* Define to a 32-bit signed integer type if one exists */ +#define __libelf_i32_t int + +/* Define to a 32-bit unsigned integer type if one exists */ +#define __libelf_u32_t unsigned int + +/* Define to a 16-bit signed integer type if one exists */ +#define __libelf_i16_t short int + +/* Define to a 16-bit unsigned integer type if one exists */ +#define __libelf_u16_t unsigned short int + +/* + * Ok, now get the correct instance of elf.h... + */ +#ifdef __LIBELF_HEADER_ELF_H +# include __LIBELF_HEADER_ELF_H +#else /* __LIBELF_HEADER_ELF_H */ +# if __LIBELF_INTERNAL__ +# include +# else /* __LIBELF_INTERNAL__ */ +# include +# endif /* __LIBELF_INTERNAL__ */ +#endif /* __LIBELF_HEADER_ELF_H */ + +/* + * On some systems, is severely broken. Try to fix it. + */ +#ifdef __LIBELF_HEADER_ELF_H + +# ifndef ELF32_FSZ_ADDR +# define ELF32_FSZ_ADDR 4 +# define ELF32_FSZ_HALF 2 +# define ELF32_FSZ_OFF 4 +# define ELF32_FSZ_SWORD 4 +# define ELF32_FSZ_WORD 4 +# endif /* ELF32_FSZ_ADDR */ + +# ifndef STN_UNDEF +# define STN_UNDEF 0 +# endif /* STN_UNDEF */ + +# if __LIBELF64 + +# ifndef ELF64_FSZ_ADDR +# define ELF64_FSZ_ADDR 8 +# define ELF64_FSZ_HALF 2 +# define ELF64_FSZ_OFF 8 +# define ELF64_FSZ_SWORD 4 +# define ELF64_FSZ_WORD 4 +# define ELF64_FSZ_SXWORD 8 +# define ELF64_FSZ_XWORD 8 +# endif /* ELF64_FSZ_ADDR */ + +# ifndef ELF64_ST_BIND +# define ELF64_ST_BIND(i) ((i)>>4) +# define ELF64_ST_TYPE(i) ((i)&0xf) +# define ELF64_ST_INFO(b,t) (((b)<<4)+((t)&0xf)) +# endif /* ELF64_ST_BIND */ + +# ifndef ELF64_R_SYM +# define ELF64_R_SYM(i) ((Elf64_Xword)(i)>>32) +# define ELF64_R_TYPE(i) ((i)&0xffffffffL) +# define ELF64_R_INFO(s,t) (((Elf64_Xword)(s)<<32)+((t)&0xffffffffL)) +# endif /* ELF64_R_SYM */ + +# if __LIBELF64_LINUX +typedef __libelf_u64_t Elf64_Addr; +typedef __libelf_u16_t Elf64_Half; +typedef __libelf_u64_t Elf64_Off; +typedef __libelf_i32_t Elf64_Sword; +typedef __libelf_u32_t Elf64_Word; +typedef __libelf_i64_t Elf64_Sxword; +typedef __libelf_u64_t Elf64_Xword; +# endif /* __LIBELF64_LINUX */ + +# endif /* __LIBELF64 */ +#endif /* __LIBELF_HEADER_ELF_H */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/update.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/update.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1019 @@ +/* + * update.c - implementation of the elf_update(3) function. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: update.c,v 1.32 2006/07/07 22:15:50 michael Exp $"; +#endif /* lint */ + +#include + +#if HAVE_MMAP +#include +#endif /* HAVE_MMAP */ + +static const unsigned short __encoding = ELFDATA2LSB + (ELFDATA2MSB << 8); +#define native_encoding (*(unsigned char*)&__encoding) + +#define rewrite(var,val,f) \ + do{if((var)!=(val)){(var)=(val);(f)|=ELF_F_DIRTY;}}while(0) + +#define align(var,val) \ + do{if((val)>1){(var)+=(val)-1;(var)-=(var)%(val);}}while(0) + +#undef max +#define max(a,b) ((a)>(b)?(a):(b)) + +static off_t +scn_data_layout(Elf_Scn *scn, unsigned v, unsigned type, size_t *algn, unsigned *flag) { + Elf *elf = scn->s_elf; + Elf_Data *data; + int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0; + size_t scn_align = 1; + size_t len = 0; + Scn_Data *sd; + size_t fsize; + + if (!(sd = scn->s_data_1)) { + /* no data in section */ + *algn = scn_align; + return (off_t)len; + } + /* load data from file, if any */ + if (!(data = elf_getdata(scn, NULL))) { + return (off_t)-1; + } + elf_assert(data == &sd->sd_data); + for (; sd; sd = sd->sd_link) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + + if (!valid_version(sd->sd_data.d_version)) { + return (off_t)-1; + } + + fsize = sd->sd_data.d_size; + if (fsize && type != SHT_NOBITS && valid_type(sd->sd_data.d_type)) { + if (elf->e_class == ELFCLASS32) { + fsize = _elf32_xltsize(&sd->sd_data, v, ELFDATA2LSB, 1); + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + fsize = _elf64_xltsize(&sd->sd_data, v, ELFDATA2LSB, 1); + } +#endif /* __LIBELF64 */ + else { + elf_assert(valid_class(elf->e_class)); + seterr(ERROR_UNIMPLEMENTED); + return (off_t)-1; + } + if (fsize == (size_t)-1) { + return (off_t)-1; + } + } + + if (layout) { + align(len, sd->sd_data.d_align); + scn_align = max(scn_align, sd->sd_data.d_align); + rewrite(sd->sd_data.d_off, (off_t)len, sd->sd_data_flags); + len += fsize; + } + else { + len = max(len, sd->sd_data.d_off + fsize); + } + + *flag |= sd->sd_data_flags; + } + *algn = scn_align; + return (off_t)len; +} + +static size_t +scn_entsize(const Elf *elf, unsigned version, unsigned stype) { + Elf_Type type; + + switch ((type = _elf_scn_type(stype))) { + case ELF_T_BYTE: + return 0; + case ELF_T_VDEF: + case ELF_T_VNEED: + return 0; /* What else can I do? Thank you, Sun! */ + default: + return _fsize(elf->e_class, version, type); + } +} + +static off_t +_elf32_layout(Elf *elf, unsigned *flag) { + int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0; + Elf32_Ehdr *ehdr = (Elf32_Ehdr*)elf->e_ehdr; + size_t off = 0; + unsigned version; + unsigned encoding; + size_t align_addr; + size_t entsize; + unsigned phnum; + unsigned shnum; + Elf_Scn *scn; + + *flag = elf->e_elf_flags | elf->e_phdr_flags; + + if ((version = ehdr->e_version) == EV_NONE) { + version = EV_CURRENT; + } + if (!valid_version(version)) { + seterr(ERROR_UNKNOWN_VERSION); + return -1; + } + if ((encoding = ehdr->e_ident[EI_DATA]) == ELFDATANONE) { + encoding = native_encoding; + } + if (!valid_encoding(encoding)) { + seterr(ERROR_UNKNOWN_ENCODING); + return -1; + } + entsize = _fsize(ELFCLASS32, version, ELF_T_EHDR); + elf_assert(entsize); + rewrite(ehdr->e_ehsize, entsize, elf->e_ehdr_flags); + off = entsize; + + align_addr = _fsize(ELFCLASS32, version, ELF_T_ADDR); + elf_assert(align_addr); + + if ((phnum = elf->e_phnum)) { + entsize = _fsize(ELFCLASS32, version, ELF_T_PHDR); + elf_assert(entsize); + if (layout) { + align(off, align_addr); + rewrite(ehdr->e_phoff, off, elf->e_ehdr_flags); + off += phnum * entsize; + } + else { + off = max(off, ehdr->e_phoff + phnum * entsize); + } + } + else { + entsize = 0; + if (layout) { + rewrite(ehdr->e_phoff, 0, elf->e_ehdr_flags); + } + } + if (phnum >= PN_XNUM) { + Elf_Scn *scn = elf->e_scn_1; + Elf32_Shdr *shdr = &scn->s_shdr32; + + elf_assert(scn); + elf_assert(scn->s_index == 0); + rewrite(shdr->sh_info, phnum, scn->s_shdr_flags); + *flag |= scn->s_shdr_flags; + phnum = PN_XNUM; + } + rewrite(ehdr->e_phnum, phnum, elf->e_ehdr_flags); + rewrite(ehdr->e_phentsize, entsize, elf->e_ehdr_flags); + + for (scn = elf->e_scn_1, shnum = 0; scn; scn = scn->s_link, ++shnum) { + Elf32_Shdr *shdr = &scn->s_shdr32; + size_t scn_align = 1; + off_t len; + + elf_assert(scn->s_index == shnum); + + *flag |= scn->s_scn_flags; + + if (scn->s_index == SHN_UNDEF) { + rewrite(shdr->sh_entsize, 0, scn->s_shdr_flags); + if (layout) { + rewrite(shdr->sh_offset, 0, scn->s_shdr_flags); + rewrite(shdr->sh_size, 0, scn->s_shdr_flags); + rewrite(shdr->sh_addralign, 0, scn->s_shdr_flags); + } + *flag |= scn->s_shdr_flags; + continue; + } + if (shdr->sh_type == SHT_NULL) { + *flag |= scn->s_shdr_flags; + continue; + } + + len = scn_data_layout(scn, version, shdr->sh_type, &scn_align, flag); + if (len == -1) { + return -1; + } + + /* + * Never override the program's choice. + */ + if (shdr->sh_entsize == 0) { + entsize = scn_entsize(elf, version, shdr->sh_type); + if (entsize > 1) { + rewrite(shdr->sh_entsize, entsize, scn->s_shdr_flags); + } + } + + if (layout) { + align(off, scn_align); + rewrite(shdr->sh_offset, off, scn->s_shdr_flags); + rewrite(shdr->sh_size, (size_t)len, scn->s_shdr_flags); + rewrite(shdr->sh_addralign, scn_align, scn->s_shdr_flags); + + if (shdr->sh_type != SHT_NOBITS) { + off += (size_t)len; + } + } + else if ((size_t)len > shdr->sh_size) { + seterr(ERROR_SCN2SMALL); + return -1; + } + else { + Elf_Scn *scn2; + size_t end1, end2; + + end1 = shdr->sh_offset; + if (shdr->sh_type != SHT_NOBITS) { + end1 += shdr->sh_size; + } + if (shdr->sh_offset < off) { + /* + * check for overlapping sections + */ + for (scn2 = elf->e_scn_1; scn2; scn2 = scn2->s_link) { + if (scn2 == scn) { + break; + } + end2 = scn2->s_shdr32.sh_offset; + if (scn2->s_shdr32.sh_type != SHT_NOBITS) { + end2 += scn2->s_shdr32.sh_size; + } + if (end1 > scn2->s_shdr32.sh_offset + && end2 > shdr->sh_offset) { + seterr(ERROR_SCN_OVERLAP); + return -1; + } + } + } + if (off < end1) { + off = end1; + } + } + *flag |= scn->s_shdr_flags; + } + + if (shnum) { + entsize = _fsize(ELFCLASS32, version, ELF_T_SHDR); + elf_assert(entsize); + if (layout) { + align(off, align_addr); + rewrite(ehdr->e_shoff, off, elf->e_ehdr_flags); + off += shnum * entsize; + } + else { + off = max(off, ehdr->e_shoff + shnum * entsize); + } + } + else { + entsize = 0; + if (layout) { + rewrite(ehdr->e_shoff, 0, elf->e_ehdr_flags); + } + } + if (shnum >= SHN_LORESERVE) { + Elf_Scn *scn = elf->e_scn_1; + Elf32_Shdr *shdr = &scn->s_shdr32; + + elf_assert(scn->s_index == 0); + rewrite(shdr->sh_size, shnum, scn->s_shdr_flags); + *flag |= scn->s_shdr_flags; + shnum = 0; + } + rewrite(ehdr->e_shnum, shnum, elf->e_ehdr_flags); + rewrite(ehdr->e_shentsize, entsize, elf->e_ehdr_flags); + + rewrite(ehdr->e_ident[EI_MAG0], ELFMAG0, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_MAG1], ELFMAG1, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_MAG2], ELFMAG2, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_MAG3], ELFMAG3, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_CLASS], ELFCLASS32, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_DATA], encoding, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_VERSION], version, elf->e_ehdr_flags); + rewrite(ehdr->e_version, version, elf->e_ehdr_flags); + + *flag |= elf->e_ehdr_flags; + + return off; +} + +#if __LIBELF64 + +static off_t +_elf64_layout(Elf *elf, unsigned *flag) { + int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0; + Elf64_Ehdr *ehdr = (Elf64_Ehdr*)elf->e_ehdr; + size_t off = 0; + unsigned version; + unsigned encoding; + size_t align_addr; + size_t entsize; + unsigned phnum; + unsigned shnum; + Elf_Scn *scn; + + *flag = elf->e_elf_flags | elf->e_phdr_flags; + + if ((version = ehdr->e_version) == EV_NONE) { + version = EV_CURRENT; + } + if (!valid_version(version)) { + seterr(ERROR_UNKNOWN_VERSION); + return -1; + } + if ((encoding = ehdr->e_ident[EI_DATA]) == ELFDATANONE) { + encoding = native_encoding; + } + if (!valid_encoding(encoding)) { + seterr(ERROR_UNKNOWN_ENCODING); + return -1; + } + entsize = _fsize(ELFCLASS64, version, ELF_T_EHDR); + elf_assert(entsize); + rewrite(ehdr->e_ehsize, entsize, elf->e_ehdr_flags); + off = entsize; + + align_addr = _fsize(ELFCLASS64, version, ELF_T_ADDR); + elf_assert(align_addr); + + if ((phnum = elf->e_phnum)) { + entsize = _fsize(ELFCLASS64, version, ELF_T_PHDR); + elf_assert(entsize); + if (layout) { + align(off, align_addr); + rewrite(ehdr->e_phoff, off, elf->e_ehdr_flags); + off += phnum * entsize; + } + else { + off = max(off, ehdr->e_phoff + phnum * entsize); + } + } + else { + entsize = 0; + if (layout) { + rewrite(ehdr->e_phoff, 0, elf->e_ehdr_flags); + } + } + if (phnum >= PN_XNUM) { + Elf_Scn *scn = elf->e_scn_1; + Elf32_Shdr *shdr = &scn->s_shdr32; + + /* modify first section header, too! */ + elf_assert(scn); + elf_assert(scn->s_index == 0); + rewrite(shdr->sh_info, phnum, scn->s_shdr_flags); + *flag |= scn->s_shdr_flags; + phnum = PN_XNUM; + } + rewrite(ehdr->e_phnum, phnum, elf->e_ehdr_flags); + rewrite(ehdr->e_phentsize, entsize, elf->e_ehdr_flags); + + for (scn = elf->e_scn_1, shnum = 0; scn; scn = scn->s_link, ++shnum) { + Elf64_Shdr *shdr = &scn->s_shdr64; + size_t scn_align = 1; + off_t len; + + elf_assert(scn->s_index == shnum); + + *flag |= scn->s_scn_flags; + + if (scn->s_index == SHN_UNDEF) { + rewrite(shdr->sh_entsize, 0, scn->s_shdr_flags); + if (layout) { + rewrite(shdr->sh_offset, 0, scn->s_shdr_flags); + rewrite(shdr->sh_size, 0, scn->s_shdr_flags); + rewrite(shdr->sh_addralign, 0, scn->s_shdr_flags); + } + *flag |= scn->s_shdr_flags; + continue; + } + if (shdr->sh_type == SHT_NULL) { + *flag |= scn->s_shdr_flags; + continue; + } + + len = scn_data_layout(scn, version, shdr->sh_type, &scn_align, flag); + if (len == -1) { + return -1; + } + + /* + * Never override the program's choice. + */ + if (shdr->sh_entsize == 0) { + entsize = scn_entsize(elf, version, shdr->sh_type); + if (entsize > 1) { + rewrite(shdr->sh_entsize, entsize, scn->s_shdr_flags); + } + } + + if (layout) { + align(off, scn_align); + rewrite(shdr->sh_offset, off, scn->s_shdr_flags); + rewrite(shdr->sh_size, (size_t)len, scn->s_shdr_flags); + rewrite(shdr->sh_addralign, scn_align, scn->s_shdr_flags); + + if (shdr->sh_type != SHT_NOBITS) { + off += (size_t)len; + } + } + else if ((size_t)len > shdr->sh_size) { + seterr(ERROR_SCN2SMALL); + return -1; + } + else { + Elf_Scn *scn2; + size_t end1, end2; + + end1 = shdr->sh_offset; + if (shdr->sh_type != SHT_NOBITS) { + end1 += shdr->sh_size; + } + if (shdr->sh_offset < off) { + /* + * check for overlapping sections + */ + for (scn2 = elf->e_scn_1; scn2; scn2 = scn2->s_link) { + if (scn2 == scn) { + break; + } + end2 = scn2->s_shdr64.sh_offset; + if (scn2->s_shdr64.sh_type != SHT_NOBITS) { + end2 += scn2->s_shdr64.sh_size; + } + if (end1 > scn2->s_shdr64.sh_offset + && end2 > shdr->sh_offset) { + seterr(ERROR_SCN_OVERLAP); + return -1; + } + } + } + if (off < end1) { + off = end1; + } + } + *flag |= scn->s_shdr_flags; + } + + if (shnum) { + entsize = _fsize(ELFCLASS64, version, ELF_T_SHDR); + elf_assert(entsize); + if (layout) { + align(off, align_addr); + rewrite(ehdr->e_shoff, off, elf->e_ehdr_flags); + off += shnum * entsize; + } + else { + off = max(off, ehdr->e_shoff + shnum * entsize); + } + } + else { + entsize = 0; + if (layout) { + rewrite(ehdr->e_shoff, 0, elf->e_ehdr_flags); + } + } + if (shnum >= SHN_LORESERVE) { + Elf_Scn *scn = elf->e_scn_1; + Elf64_Shdr *shdr = &scn->s_shdr64; + + elf_assert(scn->s_index == 0); + rewrite(shdr->sh_size, shnum, scn->s_shdr_flags); + *flag |= scn->s_shdr_flags; + shnum = 0; + } + rewrite(ehdr->e_shnum, shnum, elf->e_ehdr_flags); + rewrite(ehdr->e_shentsize, entsize, elf->e_ehdr_flags); + + rewrite(ehdr->e_ident[EI_MAG0], ELFMAG0, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_MAG1], ELFMAG1, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_MAG2], ELFMAG2, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_MAG3], ELFMAG3, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_CLASS], ELFCLASS64, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_DATA], encoding, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_VERSION], version, elf->e_ehdr_flags); + rewrite(ehdr->e_version, version, elf->e_ehdr_flags); + + *flag |= elf->e_ehdr_flags; + + return off; +} + +#endif /* __LIBELF64 */ + +#define ptrinside(p,a,l) ((p)>=(a)&&(p)<(a)+(l)) +#define newptr(p,o,n) ((p)=((p)-(o))+(n)) + +static int +_elf_update_pointers(Elf *elf, char *outbuf, size_t len) { + Elf_Scn *scn; + Scn_Data *sd; + char *data, *rawdata; + + elf_assert(elf); + elf_assert(elf->e_data); + elf_assert(!elf->e_parent); + elf_assert(!elf->e_unmap_data); + elf_assert(elf->e_kind == ELF_K_ELF); + elf_assert(len >= EI_NIDENT); + + /* resize memory images */ + if (len <= elf->e_dsize) { + /* don't shorten the memory image */ + data = elf->e_data; + } + else if ((data = (char*)realloc(elf->e_data, len))) { + elf->e_dsize = len; + } + else { + seterr(ERROR_IO_2BIG); + return -1; + } + if (elf->e_rawdata == elf->e_data) { + /* update frozen raw image */ + memcpy(data, outbuf, len); + elf->e_data = elf->e_rawdata = data; + /* cooked data is stored outside the raw image */ + return 0; + } + if (elf->e_rawdata) { + /* update raw image */ + if (!(rawdata = (char*)realloc(elf->e_rawdata, len))) { + seterr(ERROR_IO_2BIG); + return -1; + } + memcpy(rawdata, outbuf, len); + elf->e_rawdata = rawdata; + } + if (data == elf->e_data) { + /* nothing more to do */ + return 0; + } + /* adjust internal pointers */ + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf == elf); + if ((sd = scn->s_data_1)) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + if (sd->sd_memdata && !sd->sd_free_data) { + elf_assert(ptrinside(sd->sd_memdata, elf->e_data, elf->e_dsize)); + if (sd->sd_data.d_buf == sd->sd_memdata) { + newptr(sd->sd_memdata, elf->e_data, data); + sd->sd_data.d_buf = sd->sd_memdata; + } + else { + newptr(sd->sd_memdata, elf->e_data, data); + } + } + } + if ((sd = scn->s_rawdata)) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + if (sd->sd_memdata && sd->sd_free_data) { + size_t off, len; + + if (elf->e_class == ELFCLASS32) { + off = scn->s_shdr32.sh_offset; + len = scn->s_shdr32.sh_size; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + off = scn->s_shdr64.sh_offset; + len = scn->s_shdr64.sh_size; + } +#endif /* __LIBELF64 */ + else { + seterr(ERROR_UNIMPLEMENTED); + return -1; + } + if (!(rawdata = (char*)realloc(sd->sd_memdata, len))) { + seterr(ERROR_IO_2BIG); + return -1; + } + memcpy(rawdata, outbuf + off, len); + if (sd->sd_data.d_buf == sd->sd_memdata) { + sd->sd_data.d_buf = rawdata; + } + sd->sd_memdata = rawdata; + } + } + } + elf->e_data = data; + return 0; +} + +#undef ptrinside +#undef newptr + +static off_t +_elf32_write(Elf *elf, char *outbuf, size_t len) { + Elf32_Ehdr *ehdr; + Elf32_Shdr *shdr; + Elf_Scn *scn; + Scn_Data *sd; + Elf_Data src; + Elf_Data dst; + unsigned encode; + + elf_assert(len); + elf_assert(elf->e_ehdr); + ehdr = (Elf32_Ehdr*)elf->e_ehdr; + encode = ehdr->e_ident[EI_DATA]; + + src.d_buf = ehdr; + src.d_type = ELF_T_EHDR; + src.d_size = _msize(ELFCLASS32, _elf_version, ELF_T_EHDR); + src.d_version = _elf_version; + dst.d_buf = outbuf; + dst.d_size = ehdr->e_ehsize; + dst.d_version = ehdr->e_version; + if (!elf32_xlatetof(&dst, &src, encode)) { + return -1; + } + + if (elf->e_phnum) { + src.d_buf = elf->e_phdr; + src.d_type = ELF_T_PHDR; + src.d_size = elf->e_phnum * _msize(ELFCLASS32, _elf_version, ELF_T_PHDR); + src.d_version = _elf_version; + dst.d_buf = outbuf + ehdr->e_phoff; + dst.d_size = elf->e_phnum * ehdr->e_phentsize; + dst.d_version = ehdr->e_version; + if (!elf32_xlatetof(&dst, &src, encode)) { + return -1; + } + } + + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf == elf); + + src.d_buf = &scn->s_uhdr; + src.d_type = ELF_T_SHDR; + src.d_size = _msize(ELFCLASS32, EV_CURRENT, ELF_T_SHDR); + src.d_version = EV_CURRENT; + dst.d_buf = outbuf + ehdr->e_shoff + scn->s_index * ehdr->e_shentsize; + dst.d_size = ehdr->e_shentsize; + dst.d_version = ehdr->e_version; + if (!elf32_xlatetof(&dst, &src, encode)) { + return -1; + } + + if (scn->s_index == SHN_UNDEF) { + continue; + } + shdr = &scn->s_shdr32; + if (shdr->sh_type == SHT_NULL || shdr->sh_type == SHT_NOBITS) { + continue; + } + /* XXX: this is probably no longer necessary */ + if (scn->s_data_1 && !elf_getdata(scn, NULL)) { + return -1; + } + for (sd = scn->s_data_1; sd; sd = sd->sd_link) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + src = sd->sd_data; + if (!src.d_size) { + continue; + } + if (!src.d_buf) { + seterr(ERROR_NULLBUF); + return -1; + } + dst.d_buf = outbuf + shdr->sh_offset + src.d_off; + dst.d_size = src.d_size; + dst.d_version = ehdr->e_version; + if (valid_type(src.d_type)) { + size_t tmp; + + tmp = _elf32_xltsize(&src, dst.d_version, ELFDATA2LSB, 1); + if (tmp == (size_t)-1) { + return -1; + } + dst.d_size = tmp; + } + else { + src.d_type = ELF_T_BYTE; + } + if (!elf32_xlatetof(&dst, &src, encode)) { + return -1; + } + } + } + + /* cleanup */ + if (elf->e_readable && _elf_update_pointers(elf, outbuf, len)) { + return -1; + } + /* NOTE: ehdr is no longer valid! */ + ehdr = (Elf32_Ehdr*)elf->e_ehdr; elf_assert(ehdr); + elf->e_encoding = ehdr->e_ident[EI_DATA]; + elf->e_version = ehdr->e_ident[EI_VERSION]; + elf->e_elf_flags &= ~ELF_F_DIRTY; + elf->e_ehdr_flags &= ~ELF_F_DIRTY; + elf->e_phdr_flags &= ~ELF_F_DIRTY; + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + scn->s_scn_flags &= ~ELF_F_DIRTY; + scn->s_shdr_flags &= ~ELF_F_DIRTY; + for (sd = scn->s_data_1; sd; sd = sd->sd_link) { + sd->sd_data_flags &= ~ELF_F_DIRTY; + } + if (elf->e_readable) { + shdr = &scn->s_shdr32; + scn->s_type = shdr->sh_type; + scn->s_size = shdr->sh_size; + scn->s_offset = shdr->sh_offset; + } + } + elf->e_size = len; + return len; +} + +#if __LIBELF64 + +static off_t +_elf64_write(Elf *elf, char *outbuf, size_t len) { + Elf64_Ehdr *ehdr; + Elf64_Shdr *shdr; + Elf_Scn *scn; + Scn_Data *sd; + Elf_Data src; + Elf_Data dst; + unsigned encode; + + elf_assert(len); + elf_assert(elf->e_ehdr); + ehdr = (Elf64_Ehdr*)elf->e_ehdr; + encode = ehdr->e_ident[EI_DATA]; + + src.d_buf = ehdr; + src.d_type = ELF_T_EHDR; + src.d_size = _msize(ELFCLASS64, _elf_version, ELF_T_EHDR); + src.d_version = _elf_version; + dst.d_buf = outbuf; + dst.d_size = ehdr->e_ehsize; + dst.d_version = ehdr->e_version; + if (!elf64_xlatetof(&dst, &src, encode)) { + return -1; + } + + if (elf->e_phnum) { + src.d_buf = elf->e_phdr; + src.d_type = ELF_T_PHDR; + src.d_size = elf->e_phnum * _msize(ELFCLASS64, _elf_version, ELF_T_PHDR); + src.d_version = _elf_version; + dst.d_buf = outbuf + ehdr->e_phoff; + dst.d_size = elf->e_phnum * ehdr->e_phentsize; + dst.d_version = ehdr->e_version; + if (!elf64_xlatetof(&dst, &src, encode)) { + return -1; + } + } + + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf == elf); + + src.d_buf = &scn->s_uhdr; + src.d_type = ELF_T_SHDR; + src.d_size = _msize(ELFCLASS64, EV_CURRENT, ELF_T_SHDR); + src.d_version = EV_CURRENT; + dst.d_buf = outbuf + ehdr->e_shoff + scn->s_index * ehdr->e_shentsize; + dst.d_size = ehdr->e_shentsize; + dst.d_version = ehdr->e_version; + if (!elf64_xlatetof(&dst, &src, encode)) { + return -1; + } + + if (scn->s_index == SHN_UNDEF) { + continue; + } + shdr = &scn->s_shdr64; + if (shdr->sh_type == SHT_NULL || shdr->sh_type == SHT_NOBITS) { + continue; + } + /* XXX: this is probably no longer necessary */ + if (scn->s_data_1 && !elf_getdata(scn, NULL)) { + return -1; + } + for (sd = scn->s_data_1; sd; sd = sd->sd_link) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + src = sd->sd_data; + if (!src.d_size) { + continue; + } + if (!src.d_buf) { + seterr(ERROR_NULLBUF); + return -1; + } + dst.d_buf = outbuf + shdr->sh_offset + src.d_off; + dst.d_size = src.d_size; + dst.d_version = ehdr->e_version; + if (valid_type(src.d_type)) { + size_t tmp; + + tmp = _elf64_xltsize(&src, dst.d_version, ELFDATA2LSB, 1); + if (tmp == (size_t)-1) { + return -1; + } + dst.d_size = tmp; + } + else { + src.d_type = ELF_T_BYTE; + } + if (!elf64_xlatetof(&dst, &src, encode)) { + return -1; + } + } + } + + /* cleanup */ + if (elf->e_readable && _elf_update_pointers(elf, outbuf, len)) { + return -1; + } + /* NOTE: ehdr is no longer valid! */ + ehdr = (Elf64_Ehdr*)elf->e_ehdr; elf_assert(ehdr); + elf->e_encoding = ehdr->e_ident[EI_DATA]; + elf->e_version = ehdr->e_ident[EI_VERSION]; + elf->e_elf_flags &= ~ELF_F_DIRTY; + elf->e_ehdr_flags &= ~ELF_F_DIRTY; + elf->e_phdr_flags &= ~ELF_F_DIRTY; + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + scn->s_scn_flags &= ~ELF_F_DIRTY; + scn->s_shdr_flags &= ~ELF_F_DIRTY; + for (sd = scn->s_data_1; sd; sd = sd->sd_link) { + sd->sd_data_flags &= ~ELF_F_DIRTY; + } + if (elf->e_readable) { + shdr = &scn->s_shdr64; + scn->s_type = shdr->sh_type; + scn->s_size = shdr->sh_size; + scn->s_offset = shdr->sh_offset; + } + } + elf->e_size = len; + return len; +} + +#endif /* __LIBELF64 */ + +static int +xwrite(int fd, char *buffer, size_t len) { + size_t done = 0; + size_t n; + + while (done < len) { + n = write(fd, buffer + done, len - done); + if (n == 0) { + /* file system full */ + return -1; + } + else if (n != (size_t)-1) { + /* some bytes written, continue */ + done += n; + } + else if (errno != EAGAIN && errno != EINTR) { + /* real error */ + return -1; + } + } + return 0; +} + +static off_t +_elf_output(Elf *elf, int fd, size_t len, off_t (*_elf_write)(Elf*, char*, size_t)) { + char *buf; + off_t err; + + elf_assert(len); +#if HAVE_FTRUNCATE + ftruncate(fd, 0); +#endif /* HAVE_FTRUNCATE */ +#if HAVE_MMAP + /* + * Make sure the file is (at least) len bytes long + */ +#if HAVE_FTRUNCATE + lseek(fd, (off_t)len, SEEK_SET); + if (ftruncate(fd, len)) { +#else /* HAVE_FTRUNCATE */ + { +#endif /* HAVE_FTRUNCATE */ + if (lseek(fd, (off_t)len - 1, SEEK_SET) != (off_t)len - 1) { + seterr(ERROR_IO_SEEK); + return -1; + } + if (xwrite(fd, "", 1)) { + seterr(ERROR_IO_WRITE); + return -1; + } + } + buf = (void*)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (buf != (char*)-1) { + if ((char)_elf_fill && !(elf->e_elf_flags & ELF_F_LAYOUT)) { + memset(buf, _elf_fill, len); + } + err = _elf_write(elf, buf, len); + munmap(buf, len); + return err; + } +#endif /* HAVE_MMAP */ + if (!(buf = (char*)malloc(len))) { + seterr(ERROR_MEM_OUTBUF); + return -1; + } + memset(buf, _elf_fill, len); + err = _elf_write(elf, buf, len); + if (err != -1 && (size_t)err == len) { + if (lseek(fd, (off_t)0, SEEK_SET)) { + seterr(ERROR_IO_SEEK); + err = -1; + } + else if (xwrite(fd, buf, len)) { + seterr(ERROR_IO_WRITE); + err = -1; + } + } + free(buf); + return err; +} + +off_t +elf_update(Elf *elf, Elf_Cmd cmd) { + unsigned flag; + off_t len; + + if (!elf) { + return -1; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (cmd == ELF_C_WRITE) { + if (!elf->e_writable) { + seterr(ERROR_RDONLY); + return -1; + } + if (elf->e_disabled) { + seterr(ERROR_FDDISABLED); + return -1; + } + } + else if (cmd != ELF_C_NULL) { + seterr(ERROR_INVALID_CMD); + return -1; + } + + if (!elf->e_ehdr) { + seterr(ERROR_NOEHDR); + } + else if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_class == ELFCLASS32) { + len = _elf32_layout(elf, &flag); + if (len != -1 && cmd == ELF_C_WRITE && (flag & ELF_F_DIRTY)) { + len = _elf_output(elf, elf->e_fd, (size_t)len, _elf32_write); + } + return len; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + len = _elf64_layout(elf, &flag); + if (len != -1 && cmd == ELF_C_WRITE && (flag & ELF_F_DIRTY)) { + len = _elf_output(elf, elf->e_fd, (size_t)len, _elf64_write); + } + return len; + } +#endif /* __LIBELF64 */ + else if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return -1; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/verdef.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/verdef.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,241 @@ +/* + * verdef.h - copy versioning information. + * Copyright (C) 2001 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef lint +static const char verdef_h_rcsid[] = "@(#) $Id: verdef.h,v 1.12 2006/07/27 22:56:11 michael Exp $"; +#endif /* lint */ + +#if VER_DEF_CURRENT != 1 +#error libelf currently does not support VER_DEF_CURRENT != 1 +#endif /* VER_DEF_CURRENT != 1 */ + +#if TOFILE + +static void +__store_verdaux(verdaux_ftype *dst, const verdaux_mtype *src, unsigned enc) { + if (enc == ELFDATA2LSB) { + __store_u32L(dst->vda_name, src->vda_name); + __store_u32L(dst->vda_next, src->vda_next); + } + else { + __store_u32M(dst->vda_name, src->vda_name); + __store_u32M(dst->vda_next, src->vda_next); + } +} + +static void +__store_verdef(verdef_ftype *dst, const verdef_mtype *src, unsigned enc) { + if (enc == ELFDATA2LSB) { + __store_u16L(dst->vd_version, src->vd_version); + __store_u16L(dst->vd_flags, src->vd_flags); + __store_u16L(dst->vd_ndx, src->vd_ndx); + __store_u16L(dst->vd_cnt, src->vd_cnt); + __store_u32L(dst->vd_hash, src->vd_hash); + __store_u32L(dst->vd_aux, src->vd_aux); + __store_u32L(dst->vd_next, src->vd_next); + } + else { + __store_u16M(dst->vd_version, src->vd_version); + __store_u16M(dst->vd_flags, src->vd_flags); + __store_u16M(dst->vd_ndx, src->vd_ndx); + __store_u16M(dst->vd_cnt, src->vd_cnt); + __store_u32M(dst->vd_hash, src->vd_hash); + __store_u32M(dst->vd_aux, src->vd_aux); + __store_u32M(dst->vd_next, src->vd_next); + } +} + +typedef verdaux_mtype verdaux_stype; +typedef verdaux_ftype verdaux_dtype; +typedef verdef_mtype verdef_stype; +typedef verdef_ftype verdef_dtype; +typedef align_mtype verdef_atype; + +#define copy_verdaux_srctotmp(d, s, e) (*(d) = *(s)) +#define copy_verdaux_tmptodst(d, s, e) __store_verdaux((d), (s), (e)) +#define copy_verdef_srctotmp(d, s, e) (*(d) = *(s)) +#define copy_verdef_tmptodst(d, s, e) __store_verdef((d), (s), (e)) + +#define translator_suffix _tof + +#else /* TOFILE */ + +static void +__load_verdaux(verdaux_mtype *dst, const verdaux_ftype *src, unsigned enc) { + if (enc == ELFDATA2LSB) { + dst->vda_name = __load_u32L(src->vda_name); + dst->vda_next = __load_u32L(src->vda_next); + } + else { + dst->vda_name = __load_u32M(src->vda_name); + dst->vda_next = __load_u32M(src->vda_next); + } +} + +static void +__load_verdef(verdef_mtype *dst, const verdef_ftype *src, unsigned enc) { + if (enc == ELFDATA2LSB) { + dst->vd_version = __load_u16L(src->vd_version); + dst->vd_flags = __load_u16L(src->vd_flags); + dst->vd_ndx = __load_u16L(src->vd_ndx); + dst->vd_cnt = __load_u16L(src->vd_cnt); + dst->vd_hash = __load_u32L(src->vd_hash); + dst->vd_aux = __load_u32L(src->vd_aux); + dst->vd_next = __load_u32L(src->vd_next); + } + else { + dst->vd_version = __load_u16M(src->vd_version); + dst->vd_flags = __load_u16M(src->vd_flags); + dst->vd_ndx = __load_u16M(src->vd_ndx); + dst->vd_cnt = __load_u16M(src->vd_cnt); + dst->vd_hash = __load_u32M(src->vd_hash); + dst->vd_aux = __load_u32M(src->vd_aux); + dst->vd_next = __load_u32M(src->vd_next); + } +} + +typedef verdaux_ftype verdaux_stype; +typedef verdaux_mtype verdaux_dtype; +typedef verdef_ftype verdef_stype; +typedef verdef_mtype verdef_dtype; +typedef align_ftype verdef_atype; + +#define copy_verdaux_srctotmp(d, s, e) __load_verdaux((d), (s), (e)) +#define copy_verdaux_tmptodst(d, s, e) (*(d) = *(s)) +#define copy_verdef_srctotmp(d, s, e) __load_verdef((d), (s), (e)) +#define copy_verdef_tmptodst(d, s, e) (*(d) = *(s)) + +#define translator_suffix _tom + +#endif /* TOFILE */ + +#define cat3(a,b,c) a##b##c +#define xlt3(p,e,s) cat3(p,e,s) +#define xltprefix(x) xlt3(x,_,class_suffix) +#define translator(x,e) xlt3(xltprefix(_elf_##x),e,translator_suffix) + +static size_t +xlt_verdef(unsigned char *dst, const unsigned char *src, size_t n, unsigned enc) { + size_t off; + + if (sizeof(verdef_stype) != sizeof(verdef_dtype) + || sizeof(verdaux_stype) != sizeof(verdaux_dtype)) { + /* never happens for ELF v1 and Verneed v1 */ + seterr(ERROR_UNIMPLEMENTED); + return (size_t)-1; + } + /* size translation shortcut */ + if (dst == NULL) { + return n; + } + if (src == NULL) { + seterr(ERROR_NULLBUF); + return (size_t)-1; + } + off = 0; + while (off + sizeof(verdef_stype) <= n) { + const verdef_stype *svd; + verdef_dtype *dvd; + verdef_mtype vd; + size_t acount; + size_t aoff; + + /* + * check for proper alignment + */ + if (off % sizeof(verdef_atype)) { + seterr(ERROR_VERDEF_FORMAT); + return (size_t)-1; + } + /* + * copy and check src + */ + svd = (verdef_stype*)(src + off); + dvd = (verdef_dtype*)(dst + off); + copy_verdef_srctotmp(&vd, svd, enc); + if (vd.vd_version < 1 + || vd.vd_version > VER_DEF_CURRENT) { + seterr(ERROR_VERDEF_VERSION); + return (size_t)-1; + } + if (vd.vd_cnt < 1 + || vd.vd_aux == 0) { + seterr(ERROR_VERDEF_FORMAT); + return (size_t)-1; + } + copy_verdef_tmptodst(dvd, &vd, enc); + /* + * copy aux array + */ + aoff = off + vd.vd_aux; + for (acount = 0; acount < vd.vd_cnt; acount++) { + const verdaux_stype *svda; + verdaux_dtype *dvda; + verdaux_mtype vda; + + /* + * are we still inside the buffer limits? + */ + if (aoff + sizeof(verdaux_stype) > n) { + break; + } + /* + * check for proper alignment + */ + if (aoff % sizeof(verdef_atype)) { + seterr(ERROR_VERDEF_FORMAT); + return (size_t)-1; + } + /* + * copy and check src + */ + svda = (verdaux_stype*)(src + aoff); + dvda = (verdaux_dtype*)(dst + aoff); + copy_verdaux_srctotmp(&vda, svda, enc); + copy_verdaux_tmptodst(dvda, &vda, enc); + /* + * advance to next verdaux + */ + if (vda.vda_next == 0) { + /* end of list */ + break; + } + aoff += vda.vda_next; + } + /* + * advance to next verdef + */ + if (vd.vd_next == 0) { + /* end of list */ + break; + } + off += vd.vd_next; + } + return n; +} + +size_t +translator(verdef,L11)(unsigned char *dst, const unsigned char *src, size_t n) { + return xlt_verdef(dst, src, n, ELFDATA2LSB); +} + +size_t +translator(verdef,M11)(unsigned char *dst, const unsigned char *src, size_t n) { + return xlt_verdef(dst, src, n, ELFDATA2MSB); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/verdef_32_tof.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/verdef_32_tof.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,53 @@ +/* +verdef_32_tof.c - copy 32-bit versioning information. +Copyright (C) 2001 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include + +#if __LIBELF_SYMBOL_VERSIONS + +#ifndef lint +static const char rcsid[] = "@(#) $Id: verdef_32_tof.c,v 1.4 2005/05/21 15:39:26 michael Exp $"; +#endif /* lint */ + +typedef Elf32_Verdaux verdaux_mtype; +typedef Elf32_Verdef verdef_mtype; +typedef Elf32_Vernaux vernaux_mtype; +typedef Elf32_Verneed verneed_mtype; +typedef Elf32_Word align_mtype; + +typedef __ext_Elf32_Verdaux verdaux_ftype; +typedef __ext_Elf32_Verdef verdef_ftype; +typedef __ext_Elf32_Vernaux vernaux_ftype; +typedef __ext_Elf32_Verneed verneed_ftype; +typedef __ext_Elf32_Word align_ftype; + +#define class_suffix 32 + +#undef TOFILE +#define TOFILE 1 + +/* + * Include shared code + */ +#include "verdef.h" +#include "verneed.h" + +#endif /* __LIBELF_SYMBOL_VERSIONS */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/verdef_32_tom.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/verdef_32_tom.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,53 @@ +/* +verdef_32_tom.c - copy 32-bit versioning information. +Copyright (C) 2001 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include + +#if __LIBELF_SYMBOL_VERSIONS + +#ifndef lint +static const char rcsid[] = "@(#) $Id: verdef_32_tom.c,v 1.4 2005/05/21 15:39:27 michael Exp $"; +#endif /* lint */ + +typedef Elf32_Verdaux verdaux_mtype; +typedef Elf32_Verdef verdef_mtype; +typedef Elf32_Vernaux vernaux_mtype; +typedef Elf32_Verneed verneed_mtype; +typedef Elf32_Word align_mtype; + +typedef __ext_Elf32_Verdaux verdaux_ftype; +typedef __ext_Elf32_Verdef verdef_ftype; +typedef __ext_Elf32_Vernaux vernaux_ftype; +typedef __ext_Elf32_Verneed verneed_ftype; +typedef __ext_Elf32_Word align_ftype; + +#define class_suffix 32 + +#undef TOFILE +#define TOFILE 0 + +/* + * Include shared code + */ +#include "verdef.h" +#include "verneed.h" + +#endif /* __LIBELF_SYMBOL_VERSIONS */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/verdef_64_tof.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/verdef_64_tof.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,53 @@ +/* +verdef_64_tof.c - copy 64-bit versioning information. +Copyright (C) 2001 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include + +#if __LIBELF64 && __LIBELF_SYMBOL_VERSIONS + +#ifndef lint +static const char rcsid[] = "@(#) $Id: verdef_64_tof.c,v 1.4 2005/05/21 15:39:27 michael Exp $"; +#endif /* lint */ + +typedef Elf64_Verdaux verdaux_mtype; +typedef Elf64_Verdef verdef_mtype; +typedef Elf64_Vernaux vernaux_mtype; +typedef Elf64_Verneed verneed_mtype; +typedef Elf64_Word align_mtype; + +typedef __ext_Elf64_Verdaux verdaux_ftype; +typedef __ext_Elf64_Verdef verdef_ftype; +typedef __ext_Elf64_Vernaux vernaux_ftype; +typedef __ext_Elf64_Verneed verneed_ftype; +typedef __ext_Elf64_Word align_ftype; + +#define class_suffix 64 + +#undef TOFILE +#define TOFILE 1 + +/* + * Include shared code + */ +#include "verdef.h" +#include "verneed.h" + +#endif /* __LIBELF64 && __LIBELF_SYMBOL_VERSIONS */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/verdef_64_tom.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/verdef_64_tom.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,53 @@ +/* +verdef_64_tom.c - copy 64-bit versioning information. +Copyright (C) 2001 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include + +#if __LIBELF64 && __LIBELF_SYMBOL_VERSIONS + +#ifndef lint +static const char rcsid[] = "@(#) $Id: verdef_64_tom.c,v 1.4 2005/05/21 15:39:27 michael Exp $"; +#endif /* lint */ + +typedef Elf64_Verdaux verdaux_mtype; +typedef Elf64_Verdef verdef_mtype; +typedef Elf64_Vernaux vernaux_mtype; +typedef Elf64_Verneed verneed_mtype; +typedef Elf64_Word align_mtype; + +typedef __ext_Elf64_Verdaux verdaux_ftype; +typedef __ext_Elf64_Verdef verdef_ftype; +typedef __ext_Elf64_Vernaux vernaux_ftype; +typedef __ext_Elf64_Verneed verneed_ftype; +typedef __ext_Elf64_Word align_ftype; + +#define class_suffix 64 + +#undef TOFILE +#define TOFILE 0 + +/* + * Include shared code + */ +#include "verdef.h" +#include "verneed.h" + +#endif /* __LIBELF64 && __LIBELF_SYMBOL_VERSIONS */ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/verneed.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/verneed.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,245 @@ +/* + * verneed.h - copy versioning information. + * Copyright (C) 2001 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef lint +static const char verneed_h_rcsid[] = "@(#) $Id: verneed.h,v 1.12 2006/07/27 22:40:03 michael Exp $"; +#endif /* lint */ + +#if VER_NEED_CURRENT != 1 +#error libelf currently does not support VER_NEED_CURRENT != 1 +#endif /* VER_NEED_CURRENT != 1 */ + +#if TOFILE + +static void +__store_vernaux(vernaux_ftype *dst, const vernaux_mtype *src, unsigned enc) { + if (enc == ELFDATA2LSB) { + __store_u32L(dst->vna_hash, src->vna_hash); + __store_u16L(dst->vna_flags, src->vna_flags); + __store_u16L(dst->vna_other, src->vna_other); + __store_u32L(dst->vna_name, src->vna_name); + __store_u32L(dst->vna_next, src->vna_next); + } + else { + __store_u32M(dst->vna_hash, src->vna_hash); + __store_u16M(dst->vna_flags, src->vna_flags); + __store_u16M(dst->vna_other, src->vna_other); + __store_u32M(dst->vna_name, src->vna_name); + __store_u32M(dst->vna_next, src->vna_next); + } +} + +static void +__store_verneed(verneed_ftype *dst, const verneed_mtype *src, unsigned enc) { + if (enc == ELFDATA2LSB) { + __store_u16L(dst->vn_version, src->vn_version); + __store_u16L(dst->vn_cnt, src->vn_cnt); + __store_u32L(dst->vn_file, src->vn_file); + __store_u32L(dst->vn_aux, src->vn_aux); + __store_u32L(dst->vn_next, src->vn_next); + } + else { + __store_u16M(dst->vn_version, src->vn_version); + __store_u16M(dst->vn_cnt, src->vn_cnt); + __store_u32M(dst->vn_file, src->vn_file); + __store_u32M(dst->vn_aux, src->vn_aux); + __store_u32M(dst->vn_next, src->vn_next); + } +} + +typedef vernaux_mtype vernaux_stype; +typedef vernaux_ftype vernaux_dtype; +typedef verneed_mtype verneed_stype; +typedef verneed_ftype verneed_dtype; +typedef align_mtype verneed_atype; + +#define copy_vernaux_srctotmp(d, s, e) (*(d) = *(s)) +#define copy_vernaux_tmptodst(d, s, e) __store_vernaux((d), (s), (e)) +#define copy_verneed_srctotmp(d, s, e) (*(d) = *(s)) +#define copy_verneed_tmptodst(d, s, e) __store_verneed((d), (s), (e)) + +#define translator_suffix _tof + +#else /* TOFILE */ + +static void +__load_vernaux(vernaux_mtype *dst, const vernaux_ftype *src, unsigned enc) { + if (enc == ELFDATA2LSB) { + dst->vna_hash = __load_u32L(src->vna_hash); + dst->vna_flags = __load_u16L(src->vna_flags); + dst->vna_other = __load_u16L(src->vna_other); + dst->vna_name = __load_u32L(src->vna_name); + dst->vna_next = __load_u32L(src->vna_next); + } + else { + dst->vna_hash = __load_u32M(src->vna_hash); + dst->vna_flags = __load_u16M(src->vna_flags); + dst->vna_other = __load_u16M(src->vna_other); + dst->vna_name = __load_u32M(src->vna_name); + dst->vna_next = __load_u32M(src->vna_next); + } +} + +static void +__load_verneed(verneed_mtype *dst, const verneed_ftype *src, unsigned enc) { + if (enc == ELFDATA2LSB) { + dst->vn_version = __load_u16L(src->vn_version); + dst->vn_cnt = __load_u16L(src->vn_cnt); + dst->vn_file = __load_u32L(src->vn_file); + dst->vn_aux = __load_u32L(src->vn_aux); + dst->vn_next = __load_u32L(src->vn_next); + } + else { + dst->vn_version = __load_u16M(src->vn_version); + dst->vn_cnt = __load_u16M(src->vn_cnt); + dst->vn_file = __load_u32M(src->vn_file); + dst->vn_aux = __load_u32M(src->vn_aux); + dst->vn_next = __load_u32M(src->vn_next); + } +} + +typedef vernaux_ftype vernaux_stype; +typedef vernaux_mtype vernaux_dtype; +typedef verneed_ftype verneed_stype; +typedef verneed_mtype verneed_dtype; +typedef align_ftype verneed_atype; + +#define copy_vernaux_srctotmp(d, s, e) __load_vernaux((d), (s), (e)) +#define copy_vernaux_tmptodst(d, s, e) (*(d) = *(s)) +#define copy_verneed_srctotmp(d, s, e) __load_verneed((d), (s), (e)) +#define copy_verneed_tmptodst(d, s, e) (*(d) = *(s)) + +#define translator_suffix _tom + +#endif /* TOFILE */ + +#define cat3(a,b,c) a##b##c +#define xlt3(p,e,s) cat3(p,e,s) +#define xltprefix(x) xlt3(x,_,class_suffix) +#define translator(x,e) xlt3(xltprefix(_elf_##x),e,translator_suffix) + +static size_t +xlt_verneed(unsigned char *dst, const unsigned char *src, size_t n, unsigned enc) { + size_t off; + + if (sizeof(verneed_stype) != sizeof(verneed_dtype) + || sizeof(vernaux_stype) != sizeof(vernaux_dtype)) { + /* never happens for ELF v1 and Verneed v1 */ + seterr(ERROR_UNIMPLEMENTED); + return (size_t)-1; + } + /* size translation shortcut */ + if (dst == NULL) { + return n; + } + if (src == NULL) { + seterr(ERROR_NULLBUF); + return (size_t)-1; + } + off = 0; + while (off + sizeof(verneed_stype) <= n) { + const verneed_stype *svn; + verneed_dtype *dvn; + verneed_mtype vn; + size_t acount; + size_t aoff; + + /* + * check for proper alignment + */ + if (off % sizeof(verneed_atype)) { + seterr(ERROR_VERNEED_FORMAT); + return (size_t)-1; + } + /* + * copy and check src + */ + svn = (verneed_stype*)(src + off); + dvn = (verneed_dtype*)(dst + off); + copy_verneed_srctotmp(&vn, svn, enc); + if (vn.vn_version < 1 + || vn.vn_version > VER_NEED_CURRENT) { + seterr(ERROR_VERNEED_VERSION); + return (size_t)-1; + } + if (vn.vn_cnt < 1 + || vn.vn_aux == 0) { + seterr(ERROR_VERNEED_FORMAT); + return (size_t)-1; + } + copy_verneed_tmptodst(dvn, &vn, enc); + /* + * copy aux array + */ + aoff = off + vn.vn_aux; + for (acount = 0; acount < vn.vn_cnt; acount++) { + const vernaux_stype *svna; + vernaux_dtype *dvna; + vernaux_mtype vna; + + /* + * are we still inside the buffer limits? + */ + if (aoff + sizeof(vernaux_stype) > n) { + break; + } + /* + * check for proper alignment + */ + if (aoff % sizeof(verneed_atype)) { + seterr(ERROR_VERNEED_FORMAT); + return (size_t)-1; + } + /* + * copy and check src + */ + svna = (vernaux_stype*)(src + aoff); + dvna = (vernaux_dtype*)(dst + aoff); + copy_vernaux_srctotmp(&vna, svna, enc); + copy_vernaux_tmptodst(dvna, &vna, enc); + /* + * advance to next vernaux + */ + if (vna.vna_next == 0) { + /* end of list */ + break; + } + aoff += vna.vna_next; + } + /* + * advance to next verneed + */ + if (vn.vn_next == 0) { + /* end of list */ + break; + } + off += vn.vn_next; + } + return n; +} + +size_t +translator(verneed,L11)(unsigned char *dst, const unsigned char *src, size_t n) { + return xlt_verneed(dst, src, n, ELFDATA2LSB); +} + +size_t +translator(verneed,M11)(unsigned char *dst, const unsigned char *src, size_t n) { + return xlt_verneed(dst, src, n, ELFDATA2MSB); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/version.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/version.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,44 @@ +/* + * version.c - implementation of the elf_version(3) function. + * Copyright (C) 1995 - 1998, 2007 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: version.c,v 1.7 2007/09/07 12:07:59 michael Exp $"; +#endif /* lint */ + +unsigned +elf_version(unsigned ver) { + const char *s; + unsigned tmp; + + if ((s = getenv("LIBELF_SANITY_CHECKS"))) { + _elf_sanity_checks = (int)strtol(s, (char**)NULL, 0); + } + if (ver == EV_NONE) { + return EV_CURRENT; + } + if (!valid_version(ver)) { + seterr(ERROR_UNKNOWN_VERSION); + return EV_NONE; + } + tmp = _elf_version == EV_NONE ? EV_CURRENT : _elf_version; + _elf_version = ver; + return tmp; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/x.elfext.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/x.elfext.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,175 @@ +/* + * x.elfext.c -- handle ELF format extensions + * Copyright (C) 2002 - 2006 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: x.elfext.c,v 1.3 2006/07/07 22:17:50 michael Exp $"; +#endif /* lint */ + +int +elf_getphnum(Elf *elf, size_t *resultp) { + if (!elf) { + return LIBELF_FAILURE; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + return LIBELF_FAILURE; + } + if (!elf->e_ehdr && !_elf_cook(elf)) { + return LIBELF_FAILURE; + } + if (resultp) { + *resultp = elf->e_phnum; + } + return LIBELF_SUCCESS; +} + +int +elf_getshnum(Elf *elf, size_t *resultp) { + size_t num = 0; + Elf_Scn *scn; + + if (!elf) { + return LIBELF_FAILURE; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + return LIBELF_FAILURE; + } + if (!elf->e_ehdr && !_elf_cook(elf)) { + return LIBELF_FAILURE; + } + if ((scn = elf->e_scn_n)) { + num = scn->s_index + 1; + } + if (resultp) { + *resultp = num; + } + return LIBELF_SUCCESS; +} + +int +elf_getshstrndx(Elf *elf, size_t *resultp) { + size_t num = 0; + size_t dummy; + Elf_Scn *scn; + + if (!elf) { + return LIBELF_FAILURE; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (resultp == NULL) { + resultp = &dummy; /* handle NULL pointer gracefully */ + } + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + return LIBELF_FAILURE; + } + if (!elf->e_ehdr && !_elf_cook(elf)) { + return LIBELF_FAILURE; + } + if (elf->e_class == ELFCLASS32) { + num = ((Elf32_Ehdr*)elf->e_ehdr)->e_shstrndx; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + num = ((Elf64_Ehdr*)elf->e_ehdr)->e_shstrndx; + } +#endif /* __LIBELF64 */ + else { + if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return LIBELF_FAILURE; + } + if (num != SHN_XINDEX) { + *resultp = num; + return LIBELF_SUCCESS; + } + /* + * look at first section header + */ + if (!(scn = elf->e_scn_1)) { + seterr(ERROR_NOSUCHSCN); + return LIBELF_FAILURE; + } + elf_assert(scn->s_magic == SCN_MAGIC); +#if __LIBELF64 + if (elf->e_class == ELFCLASS64) { + *resultp = scn->s_shdr64.sh_link; + return LIBELF_SUCCESS; + } +#endif /* __LIBELF64 */ + *resultp = scn->s_shdr32.sh_link; + return LIBELF_SUCCESS; +} + +int +elfx_update_shstrndx(Elf *elf, size_t value) { + size_t extvalue = 0; + Elf_Scn *scn; + + if (!elf) { + return LIBELF_FAILURE; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (value >= SHN_LORESERVE) { + extvalue = value; + value = SHN_XINDEX; + } + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + return LIBELF_FAILURE; + } + if (!elf->e_ehdr && !_elf_cook(elf)) { + return LIBELF_FAILURE; + } + if (!(scn = _elf_first_scn(elf))) { + return LIBELF_FAILURE; + } + elf_assert(scn->s_magic == SCN_MAGIC); + if (elf->e_class == ELFCLASS32) { + ((Elf32_Ehdr*)elf->e_ehdr)->e_shstrndx = value; + scn->s_shdr32.sh_link = extvalue; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + ((Elf64_Ehdr*)elf->e_ehdr)->e_shstrndx = value; + scn->s_shdr64.sh_link = extvalue; + } +#endif /* __LIBELF64 */ + else { + if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return LIBELF_FAILURE; + } + elf->e_ehdr_flags |= ELF_F_DIRTY; + scn->s_shdr_flags |= ELF_F_DIRTY; + return LIBELF_SUCCESS; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/x.movscn.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/x.movscn.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,112 @@ +/* +x.movscn.c - implementation of the elfx_movscn(3) function. +Copyright (C) 1995 - 2001, 2003 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: x.movscn.c,v 1.13 2005/05/21 15:39:27 michael Exp $"; +#endif /* lint */ + +size_t +elfx_movscn(Elf *elf, Elf_Scn *scn, Elf_Scn *after) { + Elf_Scn *prev; + Elf_Scn *tmp; + int off; + + if (!elf || !scn || !after) { + return SHN_UNDEF; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + return SHN_UNDEF; + } + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(after->s_magic == SCN_MAGIC); + if (scn->s_elf != elf || after->s_elf != elf) { + seterr(ERROR_ELFSCNMISMATCH); + return SHN_UNDEF; + } + elf_assert(elf->e_scn_1); + if (scn == elf->e_scn_1) { + seterr(ERROR_NULLSCN); + return SHN_UNDEF; + } + if (scn == after || scn == after->s_link) { + /* nothing to do */ + return scn->s_index; + } + + /* + * Find previous section. + */ + prev = NULL; + for (tmp = elf->e_scn_1; tmp->s_link; tmp = tmp->s_link) { + if (tmp->s_link == scn) { + prev = tmp; + break; + } + } + elf_assert(prev != NULL); + + /* + * Update section indices + */ + off = 0; + for (tmp = elf->e_scn_1; tmp; tmp = tmp->s_link) { + if (off) { + tmp->s_index += off; + } + if (tmp == after) { + off++; + } + else if (tmp == scn) { + off--; + } + } + elf_assert(off == 0); + + /* + * Move section. + */ + prev->s_link = scn->s_link; + scn->s_link = after->s_link; + after->s_link = scn; + scn->s_index = after->s_index + 1; + if (elf->e_scn_n == scn) { + elf->e_scn_n = prev; + } + else if (elf->e_scn_n == after) { + elf->e_scn_n = scn; + } + +#if ENABLE_DEBUG + /* + * Check section indices + */ + tmp = elf->e_scn_1; + elf_assert(tmp->s_index == 0); + while (tmp->s_link) { + elf_assert(tmp->s_link->s_index == tmp->s_index + 1); + tmp = tmp->s_link; + } +#endif /* ENABLE_DEBUG */ + + return scn->s_index; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/lib/x.remscn.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/x.remscn.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,119 @@ +/* +x.remscn.c - implementation of the elfx_remscn(3) function. +Copyright (C) 1995 - 2001, 2003 Michael Riepe + +This library 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 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: x.remscn.c,v 1.14 2005/05/21 15:39:27 michael Exp $"; +#endif /* lint */ + +size_t +elfx_remscn(Elf *elf, Elf_Scn *scn) { + Elf_Scn *pscn; + Scn_Data *sd; + Scn_Data *tmp; + size_t index; + + if (!elf || !scn) { + return SHN_UNDEF; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + return SHN_UNDEF; + } + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(elf->e_ehdr); + if (scn->s_elf != elf) { + seterr(ERROR_ELFSCNMISMATCH); + return SHN_UNDEF; + } + elf_assert(elf->e_scn_1); + if (scn == elf->e_scn_1) { + seterr(ERROR_NULLSCN); + return SHN_UNDEF; + } + + /* + * Find previous section. + */ + for (pscn = elf->e_scn_1; pscn->s_link; pscn = pscn->s_link) { + if (pscn->s_link == scn) { + break; + } + } + if (pscn->s_link != scn) { + seterr(ERROR_ELFSCNMISMATCH); + return SHN_UNDEF; + } + + /* + * Unlink section. + */ + if (elf->e_scn_n == scn) { + elf->e_scn_n = pscn; + } + pscn->s_link = scn->s_link; + index = scn->s_index; + + /* + * Free section descriptor and data. + */ + for (sd = scn->s_data_1; sd; sd = tmp) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + tmp = sd->sd_link; + if (sd->sd_free_data && sd->sd_memdata) { + free(sd->sd_memdata); + } + if (sd->sd_freeme) { + free(sd); + } + } + if ((sd = scn->s_rawdata)) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + if (sd->sd_free_data && sd->sd_memdata) { + free(sd->sd_memdata); + } + if (sd->sd_freeme) { + free(sd); + } + } + if (scn->s_freeme) { + elf_assert(scn->s_index > 0); + free(scn); + } + + /* + * Adjust section indices. + */ + for (scn = pscn->s_link; scn; scn = scn->s_link) { + elf_assert(scn->s_index > index); + scn->s_index--; + } + + /* + * Adjust section count in ELF header + */ + if (_elf_update_shnum(elf, elf->e_scn_n->s_index + 1)) { + return SHN_UNDEF; + } + return index; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/libelf.pc.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/libelf.pc.in Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: @PACKAGE@ +Description: ELF object file access library +Version: @VERSION@ +Requires: +Conflicts: +Libs: -L${libdir} -lelf +Cflags: -I${includedir}/libelf diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/mkinstalldirs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/mkinstalldirs Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,35 @@ +#!/bin/sh +# Make directory hierarchy. +# Written by Noah Friedman +# Public domain. + +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +errstatus=0 + +for file in ${1+"$@"} ; do + oIFS="${IFS}" + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set - `echo ${file} | sed -e 's@/@%@g' -e 's@^%@/@'` + IFS="${oIFS}" + + pathcomp='' + + for d in ${1+"$@"} ; do + pathcomp="${pathcomp}${d}" + + if test ! -d "${pathcomp}"; then + echo "mkdir $pathcomp" 1>&2 + mkdir "${pathcomp}" || errstatus=$? + fi + + pathcomp="${pathcomp}/" + done +done + +exit $errstatus + +# eof diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/po/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/po/Makefile.in Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,184 @@ +# po/Makefile for libelf. +# Copyright (C) 1995 - 2006 Michael Riepe +# +# This library 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 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# @(#) $Id: Makefile.in,v 1.17 2006/04/21 17:16:51 michael Exp $ + +instroot = + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +localedir = @localedir@ + +CC = @CC@ +RM = rm -f +MV = mv -f +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +GENCAT = @GENCAT@ +GMSGFMT = @GMSGFMT@ +MSGFMT = @MSGFMT@ +XGETTEXT = @XGETTEXT@ +MSGMERGE = @MSGMERGE@ + +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +DEFS = -DHAVE_CONFIG_H +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +LIBINTL = @LIBINTL@ + +# no user serviceable parts below + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ + +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +topdir = .. +subdir = po + +.SUFFIXES: +.SUFFIXES: .po .mo .gmo .msg .cat + +.po.mo: + @$(RM) $@ + $(MSGFMT) -o $@ $< + +.po.gmo: + file=$(srcdir)/`echo $*|sed 's,.*/,,'`.gmo; \ + $(RM) $$file && $(GMSGFMT) -o $$file $< + +.msg.cat: + @$(RM) $@ + $(GENCAT) $@ $< + +POFILES = @POFILES@ +GMOFILES = @GMOFILES@ +MSGFILES = @MSGFILES@ + +DISTFILES = \ + gmo2msg.c Makefile.in $(PACKAGE).pot stamp-po \ + $(POFILES) $(GMOFILES) $(MSGFILES) + +POTFILES = $(top_srcdir)/lib/errors.h + +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +INSTOBJEXT = @INSTOBJEXT@ + +all: $(CATALOGS) + +check: + +install: all install-data + +install-data: $(top_srcdir)/mkinstalldirs + catalogs="$(CATALOGS)"; for cat in $$catalogs; do \ + lang=`echo $$cat | sed 's,$(CATOBJEXT)$$,,'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(SHELL) $(top_srcdir)/mkinstalldirs $(instroot)$$dir; \ + if test -r $$cat; then \ + $(INSTALL_DATA) $$cat $(instroot)$$dir/$(PACKAGE)$(INSTOBJEXT); \ + else \ + $(INSTALL_DATA) $(srcdir)/$$cat $(instroot)$$dir/$(PACKAGE)$(INSTOBJEXT); \ + fi; \ + done + +uninstall: + catalogs="$(CATALOGS)"; for cat in $$catalogs; do \ + lang=`echo $$cat | sed 's,$(CATOBJEXT)$$,,'`; \ + $(RM) $(instroot)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + done + +mostlyclean: + $(RM) core core.* $(PACKAGE).po *.po.tmp + +clean: mostlyclean + +distclean: clean + $(RM) gmo2msg *.mo *.cat + $(RM) Makefile + +maintainer-clean: distclean + $(RM) stamp-po + +$(PACKAGE).pot: $(POTFILES) + $(XGETTEXT) -c -d$(PACKAGE) -k_ $(POTFILES) + if cmp -s $(PACKAGE).po $(srcdir)/$(PACKAGE).pot; then \ + $(RM) $(PACKAGE).po; \ + else \ + $(RM) $(srcdir)/$(PACKAGE).pot && \ + $(MV) $(PACKAGE).po $(srcdir)/$(PACKAGE).pot; \ + fi + +update-po: stamp-po +stamp-po: $(PACKAGE).pot + pofiles="$(POFILES)"; cd $(srcdir) && for po in $$pofiles; do \ + $(RM) $$po.tmp; \ + if $(MSGMERGE) $$po $(PACKAGE).pot > $$po.tmp; then \ + $(RM) $$po; \ + $(MV) $$po.tmp $$po; \ + else \ + echo "update for $$po failed!"; \ + $(RM) $$po.tmp; \ + fi; \ + done + $(RM) $@ && echo timestamp > $@ + +# Create X/Open message catalog sources from .gmo files. + +.gmo.msg: + $(MAKE) $(srcdir)/gmo2msg + cd $(srcdir) && ./gmo2msg `echo $*|sed 's,.*/,,'` + +.SUFFIXES: .c + +.c: + @$(RM) $@ + $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) \ + $(LDFLAGS) $*.c $(LIBS) $(LIBINTL) -o $@ + +INCLUDES = -I$(topdir) -I. -I$(topdir)/lib -I$(srcdir) -I$(top_srcdir)/lib + +# maintainer only + +MAINT = @MAINT@ + +distdir = $(PACKAGE)-$(VERSION) +distsubdir = $(topdir)/$(distdir)/$(subdir) +$(MAINT)dist: update-po $(DISTFILES) + if test -d $(distsubdir); then true; else mkdir $(distsubdir); fi + files="$(DISTFILES)"; for file in $$files; do \ + ln $(srcdir)/$$file $(distsubdir) >/dev/null 2>&1 || \ + cp -p $(srcdir)/$$file $(distsubdir) || exit 1; \ + done + +# For the justification of the following Makefile rules, see node +# `Automatic Remaking' in GNU Autoconf documentation. + +$(MAINT)Makefile: Makefile.in $(topdir)/config.status + cd $(topdir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/po/de.gmo Binary file tools/elf4rom/libs/libelf-0.8.10/po/de.gmo has changed diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/po/de.msg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/po/de.msg Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1 @@ +$set 1 Automatically created from de.gmo by gmo2msg diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/po/de.po --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/po/de.po Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,345 @@ +# po/de.po - German messages for libelf. +# Copyright (C) 1999 - 2003 Michael Riepe +# +# This library 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 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# @(#) $Id: de.po,v 1.16 2006/04/24 16:24:32 michael Exp $ +# +msgid "" +msgstr "" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-04-21 19:18+0200\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Date: 2001-10-06 20:40:10+0200\n" +"From: Michael Riepe \n" +"Xgettext-Options: -c -dlibelf -k_\n" +"Files: ../lib/errors.h\n" + +#: ../lib/errors.h:25 +msgid "no error" +msgstr "Kein Fehler" + +#: ../lib/errors.h:26 +msgid "unknown error" +msgstr "Unbekannter Fehler" + +#: ../lib/errors.h:27 +msgid "Internal error: unknown reason" +msgstr "Interner Fehler: Ursache unbekannt" + +#: ../lib/errors.h:28 +msgid "Internal error: not implemented" +msgstr "Interner Fehler: Diese Funktion ist nicht implementiert" + +#: ../lib/errors.h:29 +msgid "Request error: cntl(ELF_C_FDREAD) on write-only file" +msgstr "Aufruffehler: cntl(ELF_C_FDREAD) ohne Leseberechtigung" + +#: ../lib/errors.h:30 +msgid "Request error: invalid ELF_C_* argument" +msgstr "Aufruffehler: Das ELF_C_*-Argument ist ungültig" + +#: ../lib/errors.h:31 +msgid "Request error: file descriptor disabled" +msgstr "Aufruffehler: Der Zugriff auf diese Datei ist nicht mehr möglich" + +#: ../lib/errors.h:32 +msgid "Request error: not an archive" +msgstr "Aufruffehler: Die bearbeitete Datei ist kein Archiv (.a)" + +#: ../lib/errors.h:33 +msgid "Request error: offset out of range" +msgstr "Aufruffehler: Die gewünschte Byteposition liegt außerhalb der Datei" + +#: ../lib/errors.h:34 +msgid "Request error: unknown ELF version" +msgstr "Aufruffehler: unbekannte ELF-Version" + +#: ../lib/errors.h:35 +msgid "Request error: ELF_C_* argument does not match" +msgstr "Aufruffehler: Das ELF_C_*-Argument paßt nicht zu den Zugriffsrechten" + +#: ../lib/errors.h:36 +msgid "Request error: archive member begin() for writing" +msgstr "Aufruffehler: Der Archivinhalt ist nicht schreibbar" + +#: ../lib/errors.h:37 +msgid "Request error: archive/member file descriptor mismatch" +msgstr "Aufruffehler: Die Datei- und Archiv-Deskriptoren passen nicht zusammen" + +#: ../lib/errors.h:38 +msgid "Request error: not an ELF file" +msgstr "Aufruffehler: Dies ist keine ELF-Datei" + +#: ../lib/errors.h:39 +msgid "Request error: class file/memory mismatch" +msgstr "Aufruffehler: Die Datei gehört zur falschen ELF-Klasse (32/64 Bit)" + +#: ../lib/errors.h:40 +msgid "Request error: invalid ELF_T_* argument" +msgstr "Aufruffehler: Das ELF_T_*-Argument ist ungültig" + +#: ../lib/errors.h:41 +msgid "Request error: unknown data encoding" +msgstr "Aufruffehler: unbekannte Datenrepräsentation (big/little endian)" + +#: ../lib/errors.h:42 +msgid "Request error: destination buffer too small" +msgstr "Aufruffehler: Der Zielpuffer ist zu klein" + +#: ../lib/errors.h:43 +msgid "Request error: d_buf is NULL" +msgstr "Aufruffehler: d_buf ist NULL" + +#: ../lib/errors.h:44 +msgid "Request error: unknown ELF class" +msgstr "Aufruffehler: unbekannte ELF-Klasse (32/64 Bit)" + +#: ../lib/errors.h:45 +msgid "Request error: section does not belong to file" +msgstr "Aufruffehler: Der Dateiabschnitt gehört nicht zu dieser Datei" + +#: ../lib/errors.h:46 +msgid "Request error: no section at index" +msgstr "Aufruffehler: Ein Abschnitt mit dieser Nummer existiert nicht" + +#: ../lib/errors.h:47 +msgid "Request error: can't manipulate null section" +msgstr "Aufruffehler: Sie versuchen, den \"Null\"-Abschnitt zu bearbeiten" + +#: ../lib/errors.h:48 +msgid "Request error: data does not belong to section" +msgstr "" +"Aufruffehler: Dieser Datenblock gehört nicht zum angegebenen Dateiabschnitt" + +#: ../lib/errors.h:49 +msgid "Request error: no string table" +msgstr "Aufruffehler: Die Namenliste fehlt" + +#: ../lib/errors.h:50 +msgid "Request error: string table offset out of range" +msgstr "Aufruffehler: Die gewünschte Position liegt außerhalb der Namenliste" + +#: ../lib/errors.h:51 +msgid "Request error: update(ELF_C_WRITE) on read-only file" +msgstr "Aufruffehler: update(ELF_C_WRITE) ohne Schreibberechtigung" + +#: ../lib/errors.h:52 +msgid "I/O error: seek" +msgstr "Ein-/Ausgabefehler: Das Positionieren innerhalb der Datei schlug fehl" + +#: ../lib/errors.h:53 +msgid "I/O error: file too big for memory" +msgstr "Ein-/Ausgabefehler: Die Datei ist zu groß" + +#: ../lib/errors.h:54 +msgid "I/O error: raw read" +msgstr "Ein-/Ausgabefehler: Lesefehler" + +#: ../lib/errors.h:55 +msgid "I/O error: get file size" +msgstr "Ein-/Ausgabefehler: Die Dateigröße ist nicht zu ermitteln" + +#: ../lib/errors.h:56 +msgid "I/O error: output write" +msgstr "Ein-/Ausgabefehler: Schreibfehler" + +#: ../lib/errors.h:57 +msgid "I/O error: can't truncate output file" +msgstr "Ein-/Ausgabefehler: Das Verkürzen der Datei schlug fehl" + +#: ../lib/errors.h:58 +msgid "Sequence error: must set ELF version first" +msgstr "Falsche Reihenfolge: Sie müssen zuerst elf_version() aufrufen" + +#: ../lib/errors.h:59 +msgid "Sequence error: must create ELF header first" +msgstr "Falsche Reihenfolge: Sie müssen zuerst elf{32,64}_newehdr() aufrufen" + +#: ../lib/errors.h:60 +msgid "Format error: reference outside file" +msgstr "" +"Fehler in der Datei: Eine Positionsangabe zeigt auf einen Punkt außerhalb " +"der Datei" + +#: ../lib/errors.h:61 +msgid "Format error: archive header truncated" +msgstr "Fehler in der Datei: Der Archiv-Header ist unvollständig" + +#: ../lib/errors.h:62 +msgid "Format error: archive fmag" +msgstr "Fehler in der Datei: Die Archiv-Kennung ist falsch" + +#: ../lib/errors.h:63 +msgid "Format error: archive header" +msgstr "Fehler in der Datei: Der Archiv-Header ist fehlerhaft" + +#: ../lib/errors.h:64 +msgid "Format error: archive member truncated" +msgstr "Fehler in der Datei: Der Archivinhalt ist unvollständig" + +#: ../lib/errors.h:65 +msgid "Format error: archive symbol table size" +msgstr "Fehler in der Datei: Die Größe der Archiv-Symboltabelle ist falsch" + +#: ../lib/errors.h:66 +msgid "Format error: archive string table" +msgstr "Fehler in der Datei: Die Archiv-Namenliste ist defekt" + +#: ../lib/errors.h:67 +msgid "Format error: archive special name unknown" +msgstr "" +"Fehler in der Datei: Es existiert ein internes Archiv-Objekt mit unbekanntem " +"Namen" + +#: ../lib/errors.h:68 +msgid "Format error: ELF header truncated" +msgstr "Fehler in der Datei: Der ELF-Header ist unvollständig" + +#: ../lib/errors.h:69 +msgid "Format error: program header table truncated" +msgstr "Fehler in der Datei: Die ELF Program Header Table ist unvollständig" + +#: ../lib/errors.h:70 +msgid "Format error: section header table truncated" +msgstr "Fehler in der Datei: Die ELF Section Header Table ist unvollständig" + +#: ../lib/errors.h:71 +msgid "Format error: data region truncated" +msgstr "Fehler in der Datei: Ein Datenblock ist unvollständig" + +#: ../lib/errors.h:72 +msgid "Format error: program header table alignment" +msgstr "" +"Fehler in der Datei: Die ELF Program Header Table liegt nicht auf einer " +"Wortgrenze" + +#: ../lib/errors.h:73 +msgid "Format error: section header table alignment" +msgstr "" +"Fehler in der Datei: Die ELF Section Header Table liegt nicht auf einer " +"Wortgrenze" + +#: ../lib/errors.h:74 +msgid "Format error: bad parameter in Verdef record" +msgstr "Fehler in der Datei: Verdef-Datensatz enthält ungültige Parameter" + +#: ../lib/errors.h:75 +msgid "Format error: unknown Verdef version" +msgstr "Fehler in der Datei: libelf unterstützt die Verdef-Version nicht" + +#: ../lib/errors.h:76 +msgid "Format error: bad parameter in Verneed record" +msgstr "Fehler in der Datei: Verneed-Datensatz enthält ungültige Parameter" + +#: ../lib/errors.h:77 +msgid "Format error: unknown Verneed version" +msgstr "Fehler in der Datei: libelf unterstützt die Verneed-Version nicht" + +#: ../lib/errors.h:78 +msgid "Format error: bad e_shnum value" +msgstr "Fehler in der Datei: e_shnum enthält einen ungültigen Wert" + +#: ../lib/errors.h:79 +#, fuzzy +msgid "Format error: bad e_shentsize value" +msgstr "Fehler in der Datei: e_shentsize enthält einen ungültigen Wert" + +#: ../lib/errors.h:80 +#, fuzzy +msgid "Format error: bad e_phentsize value" +msgstr "Fehler in der Datei: e_phentsize enthält einen ungültigen Wert" + +#: ../lib/errors.h:81 +msgid "Format error: unterminated string in string table" +msgstr "" +"Fehler in der Datei: Der Eintrag in der String-Tabelle ist nicht terminiert" + +#: ../lib/errors.h:82 +msgid "Layout error: section size too small for data" +msgstr "" +"Layout-Fehler: Ein Dateiabschnitt ist zu kurz für die darin enthaltenen Daten" + +#: ../lib/errors.h:83 +msgid "Layout error: overlapping sections" +msgstr "Layout-Fehler: Zwei (oder mehr) Dateiabschnitte überlappen sich" + +#: ../lib/errors.h:84 +msgid "Memory error: elf descriptor" +msgstr "Zu wenig Speicher: für den Elf-Deskriptor" + +#: ../lib/errors.h:85 +msgid "Memory error: archive symbol table" +msgstr "Zu wenig Speicher: für die Archiv-Symboltabelle" + +#: ../lib/errors.h:86 +msgid "Memory error: archive member header" +msgstr "Zu wenig Speicher: für die Archiv-Verwaltungsinformationen" + +#: ../lib/errors.h:87 +msgid "Memory error: ELF header" +msgstr "Zu wenig Speicher: für den ELF-Header" + +#: ../lib/errors.h:88 +msgid "Memory error: program header table" +msgstr "Zu wenig Speicher: für die Program Header Table" + +#: ../lib/errors.h:89 +msgid "Memory error: section header table" +msgstr "Zu wenig Speicher: für die Section Header Table" + +#: ../lib/errors.h:90 +msgid "Memory error: section descriptor" +msgstr "Zu wenig Speicher: für den Elf_Scn-Deskriptor" + +#: ../lib/errors.h:91 +msgid "Memory error: section data" +msgstr "Zu wenig Speicher: für die Daten dieses Abschnitts" + +#: ../lib/errors.h:92 +msgid "Memory error: output file space" +msgstr "Zu wenig Speicher: für die Ausgabe" + +#: ../lib/errors.h:93 +msgid "Memory error: temporary buffer" +msgstr "Zu wenig Speicher: für einen temporären Puffer" + +#: ../lib/errors.h:94 +msgid "GElf error: value out of range" +msgstr "GElf-Fehler: eine Zahl ist außerhalb des darstellbaren Bereichs" + +#: ../lib/errors.h:95 +msgid "GElf error: index out of range" +msgstr "GElf-Fehler: Index außerhalb des erlaubten Bereichs" + +#: ../lib/errors.h:96 +msgid "GElf error: type mismatch" +msgstr "GElf-Fehler: Typfehler" + +#: ../lib/errors.h:97 +msgid "GElf error: not enough memory for GElf_Sym" +msgstr "GElf-Fehler: zu wenig Speicher für eine Variable vom Typ GElf_Sym" + +#: ../lib/errors.h:98 +msgid "GElf error: not enough memory for GElf_Dyn" +msgstr "GElf-Fehler: zu wenig Speicher für eine Variable vom Typ GElf_Dyn" + +#: ../lib/errors.h:99 +msgid "GElf error: not enough memory for GElf_Rela" +msgstr "GElf-Fehler: zu wenig Speicher für eine Variable vom Typ GElf_Rela" + +#: ../lib/errors.h:100 +msgid "GElf error: not enough memory for GElf_Rel" +msgstr "GElf-Fehler: zu wenig Speicher für eine Variable vom Typ GElf_Rel" diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/po/gmo2msg.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/po/gmo2msg.c Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,121 @@ +/* + * gmo2msg.c - create X/Open message source file for libelf. + * Copyright (C) 1996 - 2005 Michael Riepe + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef lint +static const char rcsid[] = "@(#) $Id: gmo2msg.c,v 1.10 2005/05/21 15:39:28 michael Exp $"; +#endif /* lint */ + +#include +#include +#include +#include +#include + +#define DOMAIN "libelf" + +static const char *msgs[] = { +#define __err__(a,b) b, +#include +#undef __err__ +}; + +int +main(int argc, char **argv) { + char buf[1024], *lang, *progname, *s; + unsigned i; + FILE *fp; + + setlocale(LC_ALL, ""); + + if (*argv && (progname = strrchr(argv[0], '/'))) { + progname++; + } + else if (!(progname = *argv)) { + progname = "gmo2msg"; + } + + if (argc <= 1 || !(lang = argv[1])) { + fprintf(stderr, "Usage: gmo2msg \n"); + exit(1); + } + + /* + * Fool gettext... + */ + unlink(DOMAIN ".mo"); + unlink("LC_MESSAGES"); + unlink(lang); + sprintf(buf, "%s.gmo", lang); + if (link(buf, DOMAIN ".mo") == -1) { + fprintf(stderr, "Cannot link %s to " DOMAIN ".mo\n", buf); + perror(""); + exit(1); + } + symlink(".", "LC_MESSAGES"); + symlink(".", lang); + textdomain(DOMAIN); + getcwd(buf, sizeof(buf)); + bindtextdomain(DOMAIN, buf); + + sprintf(buf, "%s.msg", lang); + unlink(buf); + if (!(fp = fopen(buf, "w"))) { + perror(buf); + exit(1); + } + + fprintf(fp, "$set 1 Automatically created from %s.gmo by %s\n", lang, progname); + + /* + * Translate messages. + */ + setlocale(LC_MESSAGES, lang); + if ((s = gettext("")) && (s = strdup(s))) { + s = strtok(s, "\n"); + while (s) { + fprintf(fp, "$ %s\n", s); + s = strtok(NULL, "\n"); + } + } + /* + * Assume that messages contain printable ASCII characters ONLY. + * That means no tabs, linefeeds etc. + */ + for (i = 0; i < sizeof(msgs)/sizeof(*msgs); i++) { + s = gettext(msgs[i]); + if (s != msgs[i] && strcmp(s, msgs[i]) != 0) { + fprintf(fp, "$ \n$ Original message: %s\n", msgs[i]); + fprintf(fp, "%u %s\n", i + 1, s); + } + } + setlocale(LC_MESSAGES, ""); + + if (fclose(fp)) { + perror("writing output file"); + exit(1); + } + + /* + * Cleanup. + */ + unlink(DOMAIN ".mo"); + unlink("LC_MESSAGES"); + unlink(lang); + exit(0); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/po/libelf.pot --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/po/libelf.pot Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,321 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-04-21 19:18+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../lib/errors.h:25 +msgid "no error" +msgstr "" + +#: ../lib/errors.h:26 +msgid "unknown error" +msgstr "" + +#: ../lib/errors.h:27 +msgid "Internal error: unknown reason" +msgstr "" + +#: ../lib/errors.h:28 +msgid "Internal error: not implemented" +msgstr "" + +#: ../lib/errors.h:29 +msgid "Request error: cntl(ELF_C_FDREAD) on write-only file" +msgstr "" + +#: ../lib/errors.h:30 +msgid "Request error: invalid ELF_C_* argument" +msgstr "" + +#: ../lib/errors.h:31 +msgid "Request error: file descriptor disabled" +msgstr "" + +#: ../lib/errors.h:32 +msgid "Request error: not an archive" +msgstr "" + +#: ../lib/errors.h:33 +msgid "Request error: offset out of range" +msgstr "" + +#: ../lib/errors.h:34 +msgid "Request error: unknown ELF version" +msgstr "" + +#: ../lib/errors.h:35 +msgid "Request error: ELF_C_* argument does not match" +msgstr "" + +#: ../lib/errors.h:36 +msgid "Request error: archive member begin() for writing" +msgstr "" + +#: ../lib/errors.h:37 +msgid "Request error: archive/member file descriptor mismatch" +msgstr "" + +#: ../lib/errors.h:38 +msgid "Request error: not an ELF file" +msgstr "" + +#: ../lib/errors.h:39 +msgid "Request error: class file/memory mismatch" +msgstr "" + +#: ../lib/errors.h:40 +msgid "Request error: invalid ELF_T_* argument" +msgstr "" + +#: ../lib/errors.h:41 +msgid "Request error: unknown data encoding" +msgstr "" + +#: ../lib/errors.h:42 +msgid "Request error: destination buffer too small" +msgstr "" + +#: ../lib/errors.h:43 +msgid "Request error: d_buf is NULL" +msgstr "" + +#: ../lib/errors.h:44 +msgid "Request error: unknown ELF class" +msgstr "" + +#: ../lib/errors.h:45 +msgid "Request error: section does not belong to file" +msgstr "" + +#: ../lib/errors.h:46 +msgid "Request error: no section at index" +msgstr "" + +#: ../lib/errors.h:47 +msgid "Request error: can't manipulate null section" +msgstr "" + +#: ../lib/errors.h:48 +msgid "Request error: data does not belong to section" +msgstr "" + +#: ../lib/errors.h:49 +msgid "Request error: no string table" +msgstr "" + +#: ../lib/errors.h:50 +msgid "Request error: string table offset out of range" +msgstr "" + +#: ../lib/errors.h:51 +msgid "Request error: update(ELF_C_WRITE) on read-only file" +msgstr "" + +#: ../lib/errors.h:52 +msgid "I/O error: seek" +msgstr "" + +#: ../lib/errors.h:53 +msgid "I/O error: file too big for memory" +msgstr "" + +#: ../lib/errors.h:54 +msgid "I/O error: raw read" +msgstr "" + +#: ../lib/errors.h:55 +msgid "I/O error: get file size" +msgstr "" + +#: ../lib/errors.h:56 +msgid "I/O error: output write" +msgstr "" + +#: ../lib/errors.h:57 +msgid "I/O error: can't truncate output file" +msgstr "" + +#: ../lib/errors.h:58 +msgid "Sequence error: must set ELF version first" +msgstr "" + +#: ../lib/errors.h:59 +msgid "Sequence error: must create ELF header first" +msgstr "" + +#: ../lib/errors.h:60 +msgid "Format error: reference outside file" +msgstr "" + +#: ../lib/errors.h:61 +msgid "Format error: archive header truncated" +msgstr "" + +#: ../lib/errors.h:62 +msgid "Format error: archive fmag" +msgstr "" + +#: ../lib/errors.h:63 +msgid "Format error: archive header" +msgstr "" + +#: ../lib/errors.h:64 +msgid "Format error: archive member truncated" +msgstr "" + +#: ../lib/errors.h:65 +msgid "Format error: archive symbol table size" +msgstr "" + +#: ../lib/errors.h:66 +msgid "Format error: archive string table" +msgstr "" + +#: ../lib/errors.h:67 +msgid "Format error: archive special name unknown" +msgstr "" + +#: ../lib/errors.h:68 +msgid "Format error: ELF header truncated" +msgstr "" + +#: ../lib/errors.h:69 +msgid "Format error: program header table truncated" +msgstr "" + +#: ../lib/errors.h:70 +msgid "Format error: section header table truncated" +msgstr "" + +#: ../lib/errors.h:71 +msgid "Format error: data region truncated" +msgstr "" + +#: ../lib/errors.h:72 +msgid "Format error: program header table alignment" +msgstr "" + +#: ../lib/errors.h:73 +msgid "Format error: section header table alignment" +msgstr "" + +#: ../lib/errors.h:74 +msgid "Format error: bad parameter in Verdef record" +msgstr "" + +#: ../lib/errors.h:75 +msgid "Format error: unknown Verdef version" +msgstr "" + +#: ../lib/errors.h:76 +msgid "Format error: bad parameter in Verneed record" +msgstr "" + +#: ../lib/errors.h:77 +msgid "Format error: unknown Verneed version" +msgstr "" + +#: ../lib/errors.h:78 +msgid "Format error: bad e_shnum value" +msgstr "" + +#: ../lib/errors.h:79 +msgid "Format error: bad e_shentsize value" +msgstr "" + +#: ../lib/errors.h:80 +msgid "Format error: bad e_phentsize value" +msgstr "" + +#: ../lib/errors.h:81 +msgid "Format error: unterminated string in string table" +msgstr "" + +#: ../lib/errors.h:82 +msgid "Layout error: section size too small for data" +msgstr "" + +#: ../lib/errors.h:83 +msgid "Layout error: overlapping sections" +msgstr "" + +#: ../lib/errors.h:84 +msgid "Memory error: elf descriptor" +msgstr "" + +#: ../lib/errors.h:85 +msgid "Memory error: archive symbol table" +msgstr "" + +#: ../lib/errors.h:86 +msgid "Memory error: archive member header" +msgstr "" + +#: ../lib/errors.h:87 +msgid "Memory error: ELF header" +msgstr "" + +#: ../lib/errors.h:88 +msgid "Memory error: program header table" +msgstr "" + +#: ../lib/errors.h:89 +msgid "Memory error: section header table" +msgstr "" + +#: ../lib/errors.h:90 +msgid "Memory error: section descriptor" +msgstr "" + +#: ../lib/errors.h:91 +msgid "Memory error: section data" +msgstr "" + +#: ../lib/errors.h:92 +msgid "Memory error: output file space" +msgstr "" + +#: ../lib/errors.h:93 +msgid "Memory error: temporary buffer" +msgstr "" + +#: ../lib/errors.h:94 +msgid "GElf error: value out of range" +msgstr "" + +#: ../lib/errors.h:95 +msgid "GElf error: index out of range" +msgstr "" + +#: ../lib/errors.h:96 +msgid "GElf error: type mismatch" +msgstr "" + +#: ../lib/errors.h:97 +msgid "GElf error: not enough memory for GElf_Sym" +msgstr "" + +#: ../lib/errors.h:98 +msgid "GElf error: not enough memory for GElf_Dyn" +msgstr "" + +#: ../lib/errors.h:99 +msgid "GElf error: not enough memory for GElf_Rela" +msgstr "" + +#: ../lib/errors.h:100 +msgid "GElf error: not enough memory for GElf_Rel" +msgstr "" diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/po/stamp-po --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/po/stamp-po Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1 @@ +timestamp diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/libs/libelf-0.8.10/stamp-h.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/stamp-h.in Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,1 @@ +timestamp diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/COPYING --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/COPYING Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + 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, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public 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. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/COPYING.LESSER --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/COPYING.LESSER Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public 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. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/Makefile Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,59 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . + +CC=g++ +CFLAGS=-Wall -O3 -g3 +CPPFLAGS=-I. -I.. -I$/include/boost +BASE_CFLAGS= +LDFLAGS=-g -L$(MINGW_HOME)/local/lib +LIBS=-lelf -lboost_program_options -lboost_regex -lboost_filesystem +ELF4ROM=elf4rom.exe + +OBJS=dwarfabbrevmanager.o +OBJS+=dwarfarangesmanager.o +OBJS+=dwarfframemanager.o +OBJS+=dwarfinfomanager.o +OBJS+=dwarflinemanager.o +OBJS+=dwarflocexpr.o +OBJS+=dwarflocmanager.o +OBJS+=dwarfmanager.o +OBJS+=dwarfnamemanager.o +OBJS+=dwarfrangesmanager.o +OBJS+=dwarfutils.o +OBJS+=e32romimage.o +OBJS+=elfheader.o +OBJS+=elfphdr.o +OBJS+=elfrom.o +OBJS+=elfromerror.o +OBJS+=elfsection.o +OBJS+=elfsectionmanager.o +OBJS+=elfstringtable.o +OBJS+=elfsymboltablemanager.o +OBJS+=filefragment.o +OBJS+=inputfile.o +OBJS+=main.o +OBJS+=outputfile.o +OBJS+=processoptions.o + +%.o: %.cpp + $(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $< + +$(ELF4ROM): $(OBJS) + $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) + +clean: + rm -f $(OBJS) $(ELF4ROM) diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/defs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/defs.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef DEFS_H_ +#define DEFS_H_ + +#include +typedef std::string String; + +#if 0 +typedef char * PathName; +#endif + +typedef String PathName; + +typedef unsigned long LinearAddr; +typedef unsigned long VirtualAddr; + +#define ALIGN4(x) (((x)+ 3) & ~3) + +typedef unsigned long Uint32; +typedef long Int32; + +typedef char Byte; +typedef char * Byteptr; + +#endif /*DEFS_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/dwarfabbrevmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/dwarfabbrevmanager.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,161 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include "dwarfmanager.h" +#include "inputfile.h" + +const string DwarfAbbrevManager::iAbbrevSectionName(".debug_abbrev"); +void InfoContext::SetAbbrevOffset(size_t offset){ + if (!iContextValid){ + cerr << "Error: runtime error - SetAbbrevOffset called on invalid InfoContext\n"; + exit(EXIT_FAILURE); + } + + if (iAbbrevOffset == offset) + return; + // Save current entry (in particular the cursor value + if (iAbbrevOffset != 0xffffffff){ + AbbrevOffsetMap::iterator old = iMap.find(iAbbrevOffset); + if (old != iMap.end()) + old->second.iCursor = iAbbrevMapEntry.iCursor; + else + iMap[iAbbrevOffset] = iAbbrevMapEntry; + } + + AbbrevOffsetMap::iterator i = iMap.find(offset); + if (i != iMap.end()){ + iAbbrevMapEntry = i->second; + } else { + AbbrevMap * newMap = new AbbrevMap; + new (&iAbbrevMapEntry) AbbrevMapEntry(iSectionStart + offset, newMap); + iMap[offset] = iAbbrevMapEntry; + } + iAbbrevOffset = offset; +} + +DebugAbbrev & InfoContext::GetAbbrev(Dwarf_Word aCode){ + AbbrevMap::iterator i = iAbbrevMapEntry.iMap->find(aCode); + if (i != iAbbrevMapEntry.iMap->end()){ + return i->second; + } else { + return FindAbbrev(aCode); + } +} + +DebugAbbrev & InfoContext::FindAbbrev(Dwarf_Word aCode){ + // retrieve cursor for where we've scanned so far. + Dwarf_Byte_Ptr p = iAbbrevMapEntry.iCursor; + // NB. error if we don't find the code before section end + Dwarf_Byte_Ptr lim = iSectionEnd; + bool error = false; + bool found = false; + size_t leb128_length; + + while (!found && (p < lim)){ + +#define CHECK_ABBREV_LIM(p,l,e) { if ((p)>(l)){ e = true; break;} } +#define CHECK_DECODE_ULEB128(v,p,n,l,e) \ + DECODE_ULEB128(v,p,n)\ + CHECK_ABBREV_LIM(p,l,e); + + size_t count = 0; + //CHECK_DECODE_ULEB128(abbrev_code,p,leb128_length,lim, error); + Dwarf_Word abbrev_code = DwarfSectionManager::DecodeUnsignedLeb128(p, leb128_length); + p += leb128_length; + if (p>lim){ + error = true; + break; + } + // Might as well error here since either we've found the NULL abbrev + if (abbrev_code == 0) { + DebugAbbrev abbr(0, 0, 0, NULL, NULL); + (*iAbbrevMapEntry.iMap)[0] = abbr; + if (aCode == 0) // ??? why would it + found = true; + } + + CHECK_DECODE_ULEB128(tag,p,leb128_length,lim, error); + // don't care about 'has child' + p++; + CHECK_ABBREV_LIM(p,lim,error); + Dwarf_Byte_Ptr raw_attr_ptr = p; + Dwarf_Word attr; + Dwarf_Word attr_form; + do { + CHECK_DECODE_ULEB128(a,p,leb128_length,lim, error); + attr = a; + CHECK_DECODE_ULEB128(f,p,leb128_length,lim, error); + attr_form = f; + + if (attr != 0) + count++; + + } while (attr != 0 || attr_form != 0); + + DebugAbbrevAttrForm * list = new DebugAbbrevAttrForm[count]; + Dwarf_Byte_Ptr q=raw_attr_ptr; + for (size_t i=0 ; i < count ; i++){ + list[i].iAttr = ULEB128(q,leb128_length); + list[i].iForm = ULEB128(q,leb128_length); + } + DebugAbbrev abbr(abbrev_code, tag, count, raw_attr_ptr, list); + (*iAbbrevMapEntry.iMap)[abbrev_code] = abbr; + if (abbrev_code == aCode) + found = true; + } + if (error){ + cerr << "Error: corrupt .debug_abbrev section\n"; + exit(EXIT_FAILURE); + } + if (!found){ + cerr << "Error: abbrev code not found in .debug_abbrev section\n"; + exit(EXIT_FAILURE); + } + // record where we scanned to + iAbbrevMapEntry.iCursor = p; + // get the + AbbrevMap::iterator i = iAbbrevMapEntry.iMap->find(aCode); + if (i == iAbbrevMapEntry.iMap->end()){ + cerr << "Error: Runtime error processing .debug_abbrev section\n"; + exit(EXIT_FAILURE); + } + + return i->second; +} + +void DwarfAbbrevManager::StartContext(PathName & aName){ + Dwarf_Byte_Ptr section = GetSection(aName); + iInfoContext.Init(section, section + GetSectionSize(aName), GetSectionOffset(aName)); +} + +void DwarfAbbrevManager::EndContext(){ + iInfoContext.Reset(); +} + +void DwarfAbbrevManager::SetContextAbbrevOffset(Uint32 offset){ + iInfoContext.SetAbbrevOffset(offset); +} + +size_t DwarfAbbrevManager::GetContextSectionOffset(){ + return iInfoContext.GetSectionOffset(); +} + +DebugAbbrev & DwarfAbbrevManager::GetAbbrev(Dwarf_Word aCode){ + return iInfoContext.GetAbbrev(aCode); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/dwarfarangesmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/dwarfarangesmanager.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,94 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include "dwarfmanager.h" +#include "inputfile.h" + +const string DwarfArangesManager::iArangesSectionName(".debug_aranges"); + +void DwarfArangesManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end){ + while (start < end){ + Dwarf_Byte_Ptr data = start; + size_t offset_size, initial_length_size; + + Dwarf_Word length = READ_UNALIGNED4(data); + data += 4; + + if (length >= 0xfffffff0u) { + cerr << "Error: 64 bit DWARF not supported\n"; + exit(EXIT_FAILURE); + } else { + offset_size = 4; + initial_length_size = 4; + } + + start += length + initial_length_size; + + Dwarf_Half version = READ_UNALIGNED2(data); + data += 2; + + Dwarf_Word offset = GetValue(data, offset_size); + Dwarf_Word newOffset = CheckNewOffset(iDwarfInfoManager.GetSectionOffset(aPair.iXIPFileDetails.iElfFile), offset); + if (offset != newOffset) + WriteValue(data, offset, offset_size); + data += offset_size; + + + size_t pointer_size = *data++; + + size_t segment_size = *data++; + + if (version != 2 && version != 3){ + static bool warned = false; + if (!warned){ + cerr << "Only DWARF 2 and 3 aranges are currently supported\n"; + warned = true; + } + continue; + } + + size_t address_size = pointer_size + segment_size; + + if (address_size > 4){ + static bool warned2 = false; + if (!warned2){ + cerr << "64 bit DWARF not currently supported\n"; + warned2 = true; + } + continue; + } + + Dwarf_Byte_Ptr ranges = data; + + /* Must pad to an alignment boundary that is twice the address size. */ + size_t excess = (data - start) % (2 * address_size); + if (excess) + ranges += (2 * address_size) - excess; + + while (ranges + 2 * address_size <= start){ + LinearAddr addr = GetValue(ranges, address_size); + LinearAddr relocatedAddress = aPair.iXIPFileDetails.Relocate(addr); + if (addr != relocatedAddress) + WriteValue(ranges, relocatedAddress, address_size); + ranges += address_size; + // skip length field + ranges += address_size; + } + } +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/dwarfdefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/dwarfdefs.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,142 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef DWARFDEFS_H_ +#define DWARFDEFS_H_ + +//#include +/* to identify a cie */ + + +#define DW_CIE_ID ~(0x0) +#define DW_CIE_VERSION 1 /* DWARF2 */ +#define DW_CIE_VERSION3 3 /* DWARF3 */ +#define ABBREV_HASH_TABLE_SIZE 10 + +typedef int Dwarf_Bool; /* boolean type */ +// +// Copyright (c) 2008 Symbian Software Ltd. All rights reserved. +// + +typedef unsigned long long Dwarf_Off; /* 8 byte file offset */ +typedef unsigned long long Dwarf_Unsigned; /* 8 byte unsigned value*/ +typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */ +typedef unsigned char Dwarf_Small; /* 1 byte unsigned value */ +typedef signed long long Dwarf_Signed; /* 8 byte signed value */ +typedef unsigned long long Dwarf_Addr; /* target memory address */ + +typedef void* Dwarf_Ptr; /* host machine pointer */ + +typedef unsigned long Dwarf_Word; +typedef signed long Dwarf_Sword; + +typedef signed char Dwarf_Sbyte; +typedef unsigned char Dwarf_Ubyte; +typedef signed short Dwarf_Shalf; +typedef Dwarf_Ubyte *Dwarf_Byte_Ptr; + +/* these 2 are fixed sizes which must not vary with the +** ILP32/LP64 model. Between these two, stay at 32 bit. +*/ +typedef unsigned int Dwarf_ufixed; +typedef int Dwarf_sfixed; + +/* + In various places the code mistakenly associates + forms 8 bytes long with Dwarf_Signed or Dwarf_Unsigned + This is not a very portable assumption. + The following should be used instead for 64 bit integers. +*/ +typedef unsigned long long Dwarf_ufixed64; +typedef long long Dwarf_sfixed64; + +char * GetDwarfTag(Dwarf_Unsigned aTag); +char * GetDwarfAttr(Dwarf_Half attr); +char * GetDwarfForm(Dwarf_Half form); + +#define READ_UNALIGNED2(aPtr)ReadUnaligned2(aPtr) +static inline Dwarf_Word ReadUnaligned2(Dwarf_Byte_Ptr aPtr){ + Dwarf_Byte_Ptr p = aPtr; + return p[0] | (p[1] << 8); +} +#define READ_UNALIGNED4(aPtr)ReadUnaligned4(aPtr) +static inline Dwarf_Word ReadUnaligned4(Dwarf_Byte_Ptr aPtr){ + Dwarf_Byte_Ptr p = aPtr; + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +} +#define WRITE_UNALIGNED2(aPtr, val)WriteUnaligned2(aPtr, val) +static inline void WriteUnaligned2(Dwarf_Byte_Ptr aPtr, Dwarf_Word val){ + Dwarf_Byte_Ptr p = aPtr; + p[0] = val & 0xff; + p[1] = (val >> 8) & 0xff; +} + +#define WRITE_UNALIGNED4(aPtr, val)WriteUnaligned4(aPtr, val) +static inline void WriteUnaligned4(Dwarf_Byte_Ptr aPtr, Dwarf_Word val){ + Dwarf_Byte_Ptr p = aPtr; + p[0] = val & 0xff; + p[1] = (val >> 8) & 0xff; + p[2] = (val >> 16) & 0xff; + p[3] = (val >> 24) & 0xff; +} + +#include +static inline Dwarf_Word GetValue(Dwarf_Byte_Ptr start, size_t size){ + switch (size){ + default: + case 0: { + std::cerr << "Error: size of " << size << " not allowed\n"; + exit(EXIT_FAILURE); + } + case 2: + return READ_UNALIGNED2(start); + case 4: + return READ_UNALIGNED4(start); + case 8: { + std::cerr << "Error: 64 bit values not support yet\n"; + exit(EXIT_FAILURE); + } + } +} + +static inline void WriteValue(Dwarf_Byte_Ptr start, Dwarf_Word val, size_t size){ + switch (size){ + default: + case 0: { + std::cerr << "Error: size of " << size << " not allowed\n"; + exit(EXIT_FAILURE); + } + case 2: + WRITE_UNALIGNED2(start, val); + break; + case 4: + WRITE_UNALIGNED4(start, val); + break; + case 8: { + std::cerr << "Error: 64 bit values not support yet\n"; + exit(EXIT_FAILURE); + } + } + +} + +// TODO: for the moment just say 4 - we are dealing with 32 bit ARM for the foreseeable future +// in the future we need to figure out where to get this from... +#define ENCODED_POINTER_SIZE 4 + +#endif /*DWARFDEFS_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/dwarfframemanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/dwarfframemanager.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,283 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include "dwarfmanager.h" +#include "inputfile.h" + +const string DwarfFrameManager::iFrameSectionName(".debug_frame"); + +static inline size_t SizeOfEncodedValue (int encoding) +{ + switch (encoding & 0x7) + { + default: /* ??? */ + case 0: return ENCODED_POINTER_SIZE; + case 2: return 2; + case 3: return 4; + case 4: return 8; + } +} + +static inline bool ValueFitsSize(Dwarf_Word val, size_t size){ + switch (size){ + default: + case 0: { + cerr << "Error: size of " << size << " not allowed\n"; + exit(EXIT_FAILURE); + } + case 2: + return val <= 0xffff; + case 4: + return val <= 0xffffffff; + case 8: + return true; + } +} + + +void DwarfFrameManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){ + CiePtrEncodingMap ptrEncodingMap; + CieAugmentationMap augmentationMap; + size_t encoded_ptr_size = ENCODED_POINTER_SIZE; + size_t bytes_read; + Dwarf_Byte_Ptr start = aStart; + Dwarf_Byte_Ptr section_start = start; + Dwarf_Byte_Ptr end = aEnd; + while (start < end) { + unsigned char *augmentation_data = NULL; + unsigned long augmentation_data_len = 0; + size_t offset_size; + size_t initial_length_size; + + Dwarf_Byte_Ptr saved_start = start; + Dwarf_Word length = READ_UNALIGNED4(start); + start += 4; + + if (length == 0){ // ZERO terminator - shouldn't see this + continue; + } + + if (length >= 0xfffffff0u) { + cerr << "Error: 64 bit DWARF not supported\n"; + exit(EXIT_FAILURE); + } else { + offset_size = 4; + initial_length_size = 4; + } + + Dwarf_Byte_Ptr block_end = saved_start + length + initial_length_size; + if (block_end > end) { + cerr << "Warning: Invalid length " << length << " in FDE at 0x" + << (unsigned long)(saved_start - section_start) << " in file " << aPair.iXIPFileDetails.iElfFile << "\n"; + block_end = end; + } + Dwarf_Word cie_id = READ_UNALIGNED4(start); + if (cie_id != (Dwarf_Word)DW_CIE_ID) + WRITE_UNALIGNED4(start, cie_id + GetSectionOffset(aPair.iXIPFileDetails.iElfFile)); + start += offset_size; + + if (cie_id == (Dwarf_Word)DW_CIE_ID) { + Dwarf_Ubyte version = *start++; + + char * augmentation = (char *) start; + augmentation_data = NULL; + start = (Dwarf_Byte_Ptr) strchr ((char *) start, '\0') + 1; + + if (augmentation[0] == 'z'){ + ULEB128(start, bytes_read); + ULEB128(start, bytes_read); + + if (version == 1){ + // fc->ra = GET (1); + start++; + } else { + // fc->ra = LEB (); + ULEB128(start, bytes_read); + } + augmentation_data_len = ULEB128(start, bytes_read); + augmentation_data = start; + augmentationMap[saved_start] = augmentation_data_len; + start += augmentation_data_len; + } else if (strcmp (augmentation, "eh") == 0){ + //start += eh_addr_size; + start += 4; + // fc->code_factor = LEB (); + // fc->data_factor = SLEB (); + ULEB128(start, bytes_read); + ULEB128(start, bytes_read); + if (version == 1){ + //c->ra = GET (1); + start++; + } else { + // fc->ra = LEB (); + ULEB128(start, bytes_read); + } + } else { + ULEB128(start, bytes_read); + ULEB128(start, bytes_read); + + if (version == 1){ + // fc->ra = GET (1); + start++; + } else { + // fc->ra = LEB (); + ULEB128(start, bytes_read); + } + } + + if (augmentation_data_len){ + unsigned char *p, *q; + p = (unsigned char *) augmentation + 1; + q = augmentation_data; + Dwarf_Ubyte encoding = 0; + while (1){ + if (*p == 'L') + q++; + else if (*p == 'P') + q += 1 + SizeOfEncodedValue(*q); + else if (*p == 'R') + encoding = *q++; + else + break; + p++; + } + if (encoding) + ptrEncodingMap[saved_start] = encoding; + } + + } else { + Dwarf_Byte_Ptr look_for = section_start + cie_id; + Dwarf_Ubyte encoding = 0; + CiePtrEncodingMap::iterator iE = ptrEncodingMap.find(look_for); + if (iE != ptrEncodingMap.end()){ + encoding = iE->second; + encoded_ptr_size = SizeOfEncodedValue(encoding); + } + if ((encoding & 0x70) != DW_EH_PE_pcrel){ + // do the nasty + LinearAddr addr = GetValue(start, encoded_ptr_size); + LinearAddr relocatedAddr = aPair.iXIPFileDetails.Relocate(addr); + if (ValueFitsSize(relocatedAddr, encoded_ptr_size)){ + WriteValue(start, relocatedAddr, encoded_ptr_size); + } else { + cerr << "Warning: relocated addresses in " << GetSectionName().c_str() + << " section of " << aPair.iXIPFileDetails.iElfFile.c_str() + << " too large for encoding. Backtraces may be misleading.\n"; + } + } + start += encoded_ptr_size; + // skip the range size + start += encoded_ptr_size; + + CieAugmentationMap::iterator iP = augmentationMap.find(look_for); + if (iP != augmentationMap.end()){ + ULEB128(start, bytes_read); + start += bytes_read; + } + } + + Dwarf_Word tmp = 0; + while (start < block_end){ + unsigned op, opa; + op = *start++; + opa = op & 0x3f; + if (op & 0xc0) + op &= 0xc0; + switch (op){ + case DW_CFA_advance_loc: + break; + case DW_CFA_offset: + ULEB128(start, bytes_read); + break; + case DW_CFA_restore: + break; + case DW_CFA_set_loc: + start += encoded_ptr_size; + break; + case DW_CFA_advance_loc1: + start += 1; + break; + case DW_CFA_advance_loc2: + start += 2; + break; + case DW_CFA_advance_loc4: + start += 4; + break; + case DW_CFA_offset_extended: + case DW_CFA_val_offset: + ULEB128(start, bytes_read); + ULEB128(start, bytes_read); + break; + case DW_CFA_restore_extended: + case DW_CFA_undefined: + case DW_CFA_same_value: + ULEB128(start, bytes_read); + break; + case DW_CFA_register: + case DW_CFA_def_cfa: + ULEB128(start, bytes_read); + ULEB128(start, bytes_read); + break; + case DW_CFA_def_cfa_register: + case DW_CFA_def_cfa_offset: + ULEB128(start, bytes_read); + break; + case DW_CFA_def_cfa_expression: + tmp = ULEB128(start, bytes_read); + EditLocationExpression (start, encoded_ptr_size, tmp, aPair); + start += tmp; + break; + case DW_CFA_expression: + case DW_CFA_val_expression: + ULEB128(start, bytes_read); + tmp = ULEB128(start, bytes_read); + EditLocationExpression (start, encoded_ptr_size, tmp, aPair); + start += tmp; + break; +#ifndef DW_CFA_offset_extended_sf +// seems to be type in dwarf.h +#define DW_CFA_offset_extended_sf 0x11 + //DW_CFA_cfa_offset_extended_sf +#endif + case DW_CFA_offset_extended_sf: + case DW_CFA_val_offset_sf: + case DW_CFA_def_cfa_sf: + ULEB128(start, bytes_read); + ULEB128(start, bytes_read); + break; + case DW_CFA_def_cfa_offset_sf: + ULEB128(start, bytes_read); + break; + case DW_CFA_MIPS_advance_loc8: + start += 8; + break; + case DW_CFA_GNU_args_size: + ULEB128(start, bytes_read); + break; + case DW_CFA_GNU_negative_offset_extended: + ULEB128(start, bytes_read); + ULEB128(start, bytes_read); + break; + default: + break; + } + } + } + +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/dwarfinfomanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/dwarfinfomanager.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,566 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include +#include + +#include "dwarfmanager.h" +#include "inputfile.h" + +const string DwarfInfoManager::iInfoSectionName(".debug_info"); + +void DwarfInfoManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){ + iDwarfAbbrevManager.StartContext(aPair.iXIPFileDetails.iElfFile); + Dwarf_Byte_Ptr p = aStart; + Dwarf_Byte_Ptr e = aEnd; + while (p < e) { + p = ProcessCU(aPair, p, e); + } + iDwarfAbbrevManager.EndContext(); +} + +#define READ_DWARF_VAL(v,t,p) t v = *((t *)p); p += sizeof(t); +Dwarf_Byte_Ptr DwarfInfoManager::ProcessCU(FileShdrPair & aPair, Dwarf_Byte_Ptr s, Dwarf_Byte_Ptr e){ + Dwarf_Byte_Ptr p = s; + //Read the CU header info + // first check whether we're dealing with 32bit or 64 bit DWARF + + // TODO: must abstract over base types e.g uint32 etc. + // TODO: this might not be 4 byte aligned and so could cause problems on some + // architectures + READ_DWARF_VAL(len, Uint32, p); + if (len >= 0xfffffff0u){ + cerr << "Error: 64 bit DWARF not supported\n"; + exit(EXIT_FAILURE); + } + iLocalLength = len; + Dwarf_Byte_Ptr end = p + len; + // TODO: make sensitive to dwarf version number? + READ_DWARF_VAL(version, Dwarf_Half, p); + Uint32 abbrevOffset = *((Uint32 *)p); + // update the offset into the abbrev table + *((Uint32 *)p) = (Uint32)(abbrevOffset + iDwarfAbbrevManager.GetContextSectionOffset()); + p += sizeof(Uint32); + READ_DWARF_VAL(address_size, Byte, p); + + // TODO: if this isn't 4 we're doomed aren't we? + iAddressSize = address_size; + + iDwarfAbbrevManager.SetContextAbbrevOffset(abbrevOffset); + + // now process each DIE until end. + while (p < end) { + p = ProcessDIE(aPair, p, end); + } + + return p; +} + +void NoteProducer(FileShdrPair & aPair, Dwarf_Byte_Ptr aPtr, Dwarf_Unsigned aForm){ + + switch (aForm){ + case DW_FORM_string:{ + const char * producer = (const char *)aPtr; + const char * RvctProducer = "ARM/Thumb C/C++ Compiler, RVCT"; + const size_t RvctProducerLength = strlen(RvctProducer); + const char * GccProducer = "GNU C++"; + const size_t GccProducerLength = strlen(GccProducer); + if (!strncmp(producer, RvctProducer, RvctProducerLength)) + aPair.iXIPFileDetails.iRVCTProduced = true; + if (!strncmp(producer, GccProducer, GccProducerLength)) + aPair.iXIPFileDetails.iGCCProduced = true; + return; + } + case DW_FORM_indirect: { + size_t indir_len = 0; + Dwarf_Unsigned form_indirect = DwarfSectionManager::DecodeUnsignedLeb128(aPtr, indir_len); + if (form_indirect == DW_FORM_indirect) { + /* Eek, should never happen, will get warned later */ + return; + } + return NoteProducer(aPair, aPtr+indir_len, form_indirect); + } + case DW_FORM_strp: + // TODO - We need to get the string table for this -- + return; + } +} + +Dwarf_Byte_Ptr DwarfInfoManager::ProcessDIE(FileShdrPair & aPair, Dwarf_Byte_Ptr s, Dwarf_Byte_Ptr e){ + Dwarf_Byte_Ptr info_ptr = s; + size_t leb128_length; + + Dwarf_Word abbrev_code = DecodeUnsignedLeb128(info_ptr, leb128_length); + info_ptr += leb128_length; + if (abbrev_code == 0) { + return info_ptr; + } + + DebugAbbrev & abbrev = iDwarfAbbrevManager.GetAbbrev(abbrev_code); + + //cout << "Tag = " << GetDwarfTag(abbrev.iTag) << " Code = " << abbrev_code << " num attrs = " << abbrev.iCount << endl; + + for (size_t i = 0; i < abbrev.iCount; i++){ + size_t attr = abbrev.iParsed[i].iAttr; + Dwarf_Unsigned form = abbrev.iParsed[i].iForm; + //cout << "\tAttr " << GetDwarfAttr(attr) << " Form " << GetDwarfForm(form) << "\n"; + + // record anything interesting about the producer here. + if (attr == DW_AT_producer) + NoteProducer(aPair, info_ptr, form); + + if (attr > DW_AT_recursive) + info_ptr = DefaultInfoEditFn(*this, info_ptr, form, aPair); + else + info_ptr = iInfoEditFn[attr](*this, info_ptr, form, aPair); + } + + return info_ptr; +} + + +size_t DwarfInfoManager::SizeOfDieValue(Dwarf_Half aForm, Dwarf_Byte_Ptr aPtr){ + Dwarf_Unsigned length = 0; + size_t leb128_length = 0; + size_t ret_value = 0; + + switch (aForm) { + + default: /* Handles form = 0. */ + return (aForm); + + case DW_FORM_addr: + return iAddressSize; + + case DW_FORM_ref_addr: + // TODO: sort this out + return 4; // this is a 4 byte relocatable in 32 bit dwarf and 8-byte in 64 bit dwarf + + case DW_FORM_block1: + return (*aPtr) + 1; + + case DW_FORM_block2: + ret_value = READ_UNALIGNED2(aPtr) + 2; + return ret_value; + + case DW_FORM_block4: + ret_value = READ_UNALIGNED4(aPtr) + 4; + return ret_value; + + case DW_FORM_data1: + return 1; + + case DW_FORM_data2: + return 2; + + case DW_FORM_data4: + return 4; + + case DW_FORM_data8: + return 8; + + case DW_FORM_string: + return (strlen((char *) aPtr) + 1); + + case DW_FORM_block: + length = DecodeUnsignedLeb128(aPtr, leb128_length); + return length + leb128_length; + + case DW_FORM_flag: + return 1; + + case DW_FORM_ref_udata: + DecodeUnsignedLeb128(aPtr, leb128_length); + return leb128_length; + + case DW_FORM_indirect: { + size_t indir_len = 0; + Dwarf_Unsigned form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); + if (form_indirect == DW_FORM_indirect) { + /* Eek, should never happen */ + cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; + } + return indir_len + SizeOfDieValue(form_indirect, aPtr+indir_len); + } + + case DW_FORM_ref1: + return 1; + + case DW_FORM_ref2: + return 2; + + case DW_FORM_ref4: + return 4; + + case DW_FORM_ref8: + return 8; + + case DW_FORM_sdata: + DecodeSignedLeb128(aPtr, leb128_length); + return leb128_length; + + case DW_FORM_strp: + // TODO: sort this out + return 4; // this is a 4 byte relocatable in 32 bit dwarf and 8-byte in 64 bit dwarf + + case DW_FORM_udata: + DecodeUnsignedLeb128(aPtr, leb128_length); + return leb128_length; + } +} + +Dwarf_Byte_Ptr DwarfInfoManager::DefaultInfoEditFn(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ + return aPtr + aManager.SizeOfDieValue(aForm, aPtr); +} + +Dwarf_Byte_Ptr DwarfInfoManager::ErrorInfoEditFn(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ + cerr << "Error: Undefined DW_FORM value: " << aForm << "\n" ; + exit(EXIT_FAILURE); + return aPtr; +} + +// TODO: implicitly only deals with 32-bit DWARF +// Called from other edit functions to deal with blocks that contain location expressions. +Dwarf_Byte_Ptr DwarfInfoManager::InfoEditLocExpr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ + Dwarf_Unsigned length = 0; + bool locExpr = false; + Dwarf_Byte_Ptr block = aPtr; + if (aForm == DW_FORM_block1) { + locExpr = true; + length = block[0]; + block++; + aPtr += (length + 1); + } else if (aForm == DW_FORM_block2) { + locExpr = true; + length = READ_UNALIGNED2(block); + block += 2; + aPtr += (length + 2); + } else if (aForm == DW_FORM_block4) { + locExpr = true; + length = READ_UNALIGNED4(block); + block += 4; + aPtr += (length + 4); + } else if (aForm == DW_FORM_block) { + locExpr = true; + size_t leb_length = 0; + length = DecodeUnsignedLeb128(block, leb_length); + block += leb_length; + aPtr += (length + leb_length); + } + + if (locExpr){ + EditLocationExpression (block, aManager.iAddressSize, length, aPair); + return aPtr; + } else if (aForm == DW_FORM_indirect){ + size_t indir_len = 0; + Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); + if (form_indirect == DW_FORM_indirect) { + /* Eek, should never happen */ + cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; + } + return InfoEditLocExpr(aManager, aPtr+indir_len, form_indirect, aPair); + + } else + return aPtr + aManager.SizeOfDieValue(aForm, aPtr); +} +// TODO: implicitly only deals with 32-bit DWARF +Dwarf_Byte_Ptr DwarfInfoManager::InfoEditAddress(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ + if (aForm == DW_FORM_addr){ + LinearAddr addr = READ_UNALIGNED4(aPtr); + LinearAddr relocatedAddr = aPair.iXIPFileDetails.Relocate(addr); + WRITE_UNALIGNED4(aPtr, relocatedAddr); + return aPtr + 4; + } else if (aForm == DW_FORM_indirect){ + size_t indir_len = 0; + Dwarf_Unsigned form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); + if (form_indirect == DW_FORM_indirect) { + /* Eek, should never happen */ + cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; + } + return InfoEditAddress(aManager, aPtr+indir_len, form_indirect, aPair); + + } else + return aPtr + aManager.SizeOfDieValue(aForm, aPtr); +} + +// TODO: implicitly only deals with 32-bit DWARF +Dwarf_Byte_Ptr DwarfInfoManager::InfoEditLinePtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ + if (aForm == DW_FORM_data4){ + size_t offset = READ_UNALIGNED4(aPtr); + size_t newOffset = aManager.iDwarfManager.GetLineSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset; + if (offset != newOffset) + WRITE_UNALIGNED4(aPtr, newOffset); + return aPtr + 4; + } else if (aForm == DW_FORM_indirect){ + size_t indir_len = 0; + Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); + if (form_indirect == DW_FORM_indirect) { + /* Eek, should never happen */ + cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; + } + return InfoEditLinePtr(aManager, aPtr+indir_len, form_indirect, aPair); + + } else + return aPtr + aManager.SizeOfDieValue(aForm, aPtr); +} + +// TODO: implicitly only deals with 32-bit DWARF +Dwarf_Byte_Ptr DwarfInfoManager::InfoEditLocListPtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ + if (aForm == DW_FORM_data4){ + size_t offset = READ_UNALIGNED4(aPtr); + size_t newOffset = aManager.iDwarfManager.GetLocListSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset; + if (offset != newOffset) + WRITE_UNALIGNED4(aPtr, newOffset); + return aPtr + 4; + } else if (aForm == DW_FORM_indirect){ + size_t indir_len = 0; + Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); + if (form_indirect == DW_FORM_indirect) { + /* Eek, should never happen */ + cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; + } + return InfoEditLocListPtr(aManager, aPtr+indir_len, form_indirect, aPair); + + } else + //return aPtr + aManager.SizeOfDieValue(aForm, aPtr); + return InfoEditLocExpr(aManager, aPtr, aForm, aPair); +} + + + + + +// TODO: implicitly only deals with 32-bit DWARF +Dwarf_Byte_Ptr DwarfInfoManager::InfoEditMacInfoPtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ + if (aForm == DW_FORM_data4){ + size_t offset = READ_UNALIGNED4(aPtr); + size_t newOffset = aManager.iDwarfManager.GetMacInfoSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset; + if (offset != newOffset) + WRITE_UNALIGNED4(aPtr, newOffset); + return aPtr + 4; + } else if (aForm == DW_FORM_indirect){ + size_t indir_len = 0; + Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); + if (form_indirect == DW_FORM_indirect) { + /* Eek, should never happen */ + cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; + } + return InfoEditMacInfoPtr(aManager, aPtr+indir_len, form_indirect, aPair); + + } else + return aPtr + aManager.SizeOfDieValue(aForm, aPtr); +} + +// TODO: implicitly only deals with 32-bit DWARF +Dwarf_Byte_Ptr DwarfInfoManager::InfoEditRangeListPtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ + if (aForm == DW_FORM_data4){ + size_t offset = READ_UNALIGNED4(aPtr); + size_t newOffset = aManager.iDwarfManager.GetRangesSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset; + if (offset != newOffset) + WRITE_UNALIGNED4(aPtr, newOffset); + return aPtr + 4; + } else if (aForm == DW_FORM_indirect){ + size_t indir_len = 0; + Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); + if (form_indirect == DW_FORM_indirect) { + /* Eek, should never happen */ + cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; + } + return InfoEditRangeListPtr(aManager, aPtr+indir_len, form_indirect, aPair); + + } else + return aPtr + aManager.SizeOfDieValue(aForm, aPtr); +} + +// TODO: implicitly only deals with 32-bit DWARF +Dwarf_Byte_Ptr DwarfInfoManager::InfoEditString(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ + + if (aForm == DW_FORM_strp){ + size_t offset = READ_UNALIGNED4(aPtr); + size_t newOffset = aManager.iDwarfManager.GetStrSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset; + if (offset != newOffset) + WRITE_UNALIGNED4(aPtr, newOffset); + return aPtr + 4; + } else if (aForm == DW_FORM_indirect){ + size_t indir_len = 0; + Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); + if (form_indirect == DW_FORM_indirect) { + /* Eek, should never happen */ + cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; + } + return InfoEditString(aManager, aPtr+indir_len, form_indirect, aPair); + + } else + return aPtr + aManager.SizeOfDieValue(aForm, aPtr); +} + +// TODO: implicitly only deals with 32-bit DWARF +Dwarf_Byte_Ptr DwarfInfoManager::InfoEditReference(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ + if (aForm == DW_FORM_ref_addr){ + size_t offset = READ_UNALIGNED4(aPtr); + size_t newOffset = aManager.CheckNewOffset(aManager.GetSectionOffset(aPair.iXIPFileDetails.iElfFile), offset); + if (offset != newOffset) + WRITE_UNALIGNED4(aPtr, newOffset); + return aPtr + 4; + } else if (aForm == DW_FORM_indirect){ + size_t indir_len = 0; + Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); + if (form_indirect == DW_FORM_indirect) { + /* Eek, should never happen */ + cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; + } + return InfoEditReference(aManager, aPtr+indir_len, form_indirect, aPair); + + } else + //return aPtr + aManager.SizeOfDieValue(aForm, aPtr); + return InfoEditLocExpr(aManager, aPtr, aForm, aPair); +} + +// TODO: implicitly only deals with 32-bit DWARF +// Explicitly check for *_address and *_strp then let the reference handler deal with the flag possiblity as s 'else'. +Dwarf_Byte_Ptr DwarfInfoManager::InfoEditTrampoline(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ + if (aForm == DW_FORM_addr) + return InfoEditAddress(aManager, aPtr, aForm, aPair); + else if (aForm = DW_FORM_strp) + return InfoEditString(aManager, aPtr, aForm, aPair); + else if (aForm == DW_FORM_indirect){ + size_t indir_len = 0; + Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); + if (form_indirect == DW_FORM_indirect) { + /* Eek, should never happen */ + cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; + } + return InfoEditTrampoline(aManager, aPtr+indir_len, form_indirect, aPair); + + } + else + return InfoEditReference(aManager, aPtr, aForm, aPair); +} + + +DwarfInfoManager::InfoEditFn DwarfInfoManager::iInfoEditFn [] = { + DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0 so this should never be called + DwarfInfoManager::InfoEditReference, // DW_AT_sibling 0x01 + DwarfInfoManager::InfoEditLocListPtr, // DW_AT_location 0x02 + DwarfInfoManager::InfoEditString, // DW_AT_name 0x03 + DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 4 so this should never be called + DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 5 so this should never be called + DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 6 so this should never be called + DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 7 so this should never be called + DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 8 so this should never be called + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_ordering 0x09 + // TODO: This doesn't appear in the DWARF 3 spec of 2005/12/05 :-( so just defualt it for now + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_subscr_data 0x0a + DwarfInfoManager::InfoEditReference, // DW_AT_byte_size 0x0b + DwarfInfoManager::InfoEditReference, // DW_AT_bit_offset 0x0c + DwarfInfoManager::InfoEditReference, // DW_AT_bit_size 0x0d + DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x0e so this should never be called + // TODO: This doesn't appear in the DWARF 3 spec of 2005/12/05 :-( so just defualt it for now + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_element_list 0x0f + DwarfInfoManager::InfoEditLinePtr, // DW_AT_stmt_list 0x10 + DwarfInfoManager::InfoEditAddress, // DW_AT_low_pc 0x11 + DwarfInfoManager::InfoEditAddress, // DW_AT_high_pc 0x12 + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_language 0x13 + // TODO: This doesn't appear in the DWARF 3 spec of 2005/12/05 :-( so just defualt it for now + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_member 0x14 + DwarfInfoManager::InfoEditReference, // DW_AT_discr 0x15 + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_discr_value 0x16 + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_visibility 0x17 + DwarfInfoManager::InfoEditReference, // DW_AT_import 0x18 + DwarfInfoManager::InfoEditLocListPtr, // DW_AT_string_length 0x19 + DwarfInfoManager::InfoEditReference, // DW_AT_common_reference 0x1a + DwarfInfoManager::InfoEditString, // DW_AT_comp_dir 0x1b + DwarfInfoManager::InfoEditString, // DW_AT_const_value 0x1c + DwarfInfoManager::InfoEditReference, // DW_AT_containing_type 0x1d + DwarfInfoManager::InfoEditReference, // DW_AT_default_value 0x1e + DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x1f so this should never be called + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_inline 0x20 + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_is_optional 0x21 + DwarfInfoManager::InfoEditReference, // DW_AT_lower_bound 0x22 + DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x23 so this should never be called + DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x24 so this should never be called + DwarfInfoManager::InfoEditString, // DW_AT_producer 0x25 + DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x26 so this should never be called + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_prototyped 0x27 + DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x28 so this should never be called + DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x29 so this should never be called + DwarfInfoManager::InfoEditLocListPtr, // DW_AT_return_addr 0x2a + DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x2b so this should never be called + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_start_scope 0x2c + DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x2d so this should never be called + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_bit_stride 0x2e /* DWARF3 name */ + DwarfInfoManager::InfoEditReference, // DW_AT_upper_bound 0x2f + DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x30 so this should never be called + DwarfInfoManager::InfoEditReference, // DW_AT_abstract_origin 0x31 + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_accessibility 0x32 + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_address_class 0x33 + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_artificial 0x34 + DwarfInfoManager::InfoEditReference, // DW_AT_base_types 0x35 + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_calling_convention 0x36 + DwarfInfoManager::InfoEditReference, // DW_AT_count 0x37 + DwarfInfoManager::InfoEditLocListPtr, // DW_AT_data_member_location 0x38 + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_decl_column 0x39 + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_decl_file 0x3a + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_decl_line 0x3b + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_declaration 0x3c + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_discr_list 0x3d + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_encoding 0x3e + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_external 0x3f + DwarfInfoManager::InfoEditLocListPtr, // DW_AT_frame_base 0x40 + DwarfInfoManager::InfoEditReference, // DW_AT_friend 0x41 + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_identifier_case 0x42 + DwarfInfoManager::InfoEditMacInfoPtr, // DW_AT_macro_info 0x43 + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_namelist_item 0x44 + DwarfInfoManager::InfoEditReference, // DW_AT_priority 0x45 + DwarfInfoManager::InfoEditLocListPtr, // DW_AT_segment 0x46 + DwarfInfoManager::InfoEditReference, // DW_AT_specification 0x47 + DwarfInfoManager::InfoEditLocListPtr, // DW_AT_static_link 0x48 + DwarfInfoManager::InfoEditReference, // DW_AT_type 0x49 + DwarfInfoManager::InfoEditLocListPtr, // DW_AT_use_location 0x4a + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_variable_parameter 0x4b + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_virtuality 0x4c + DwarfInfoManager::InfoEditLocListPtr, // DW_AT_vtable_elem_location 0x4d + DwarfInfoManager::InfoEditReference, // DW_AT_allocated 0x4e /* DWARF3 */ + DwarfInfoManager::InfoEditReference, // DW_AT_associated 0x4f /* DWARF3 */ + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_data_location 0x50 /* DWARF3 */ + DwarfInfoManager::InfoEditReference, // DW_AT_byte_stride 0x51 /* DWARF3f */ + DwarfInfoManager::InfoEditAddress, // DW_AT_entry_pc 0x52 /* DWARF3 */ + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_use_UTF8 0x53 /* DWARF3 */ + DwarfInfoManager::InfoEditReference, // DW_AT_extension 0x54 /* DWARF3 */ + DwarfInfoManager::InfoEditRangeListPtr, // DW_AT_ranges 0x55 /* DWARF3 */ + DwarfInfoManager::InfoEditTrampoline, // DW_AT_trampoline 0x56 /* DWARF3 */ + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_call_column 0x57 /* DWARF3 */ + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_call_file 0x58 /* DWARF3 */ + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_call_line 0x59 /* DWARF3 */ + DwarfInfoManager::InfoEditString, // DW_AT_description 0x5a /* DWARF3 */ + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_binary_scale 0x5b /* DWARF3f */ + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_decimal_scale 0x5c /* DWARF3f */ + DwarfInfoManager::InfoEditReference, // DW_AT_small 0x5d /* DWARF3f */ + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_decimal_sign 0x5e /* DWARF3f */ + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_digit_count 0x5f /* DWARF3f */ + DwarfInfoManager::InfoEditString, // DW_AT_picture_string 0x60 /* DWARF3f */ + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_mutable 0x61 /* DWARF3f */ + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_threads_scaled 0x62 /* DWARF3f */ + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_explicit 0x63 /* DWARF3f */ + DwarfInfoManager::InfoEditReference, // DW_AT_object_pointer 0x64 /* DWARF3f */ + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_endianity 0x65 /* DWARF3f */ + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_elemental 0x66 /* DWARF3f */ + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_pure 0x67 /* DWARF3f */ + DwarfInfoManager::DefaultInfoEditFn, // DW_AT_recursive 0x68 /* DWARF3f */ +}; diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/dwarflinemanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/dwarflinemanager.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,185 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include "dwarfmanager.h" +#include "inputfile.h" + +const string DwarfLineManager::iLineSectionName(".debug_line"); + +inline static size_t process_extended_line_op (FileShdrPair & aPair, Dwarf_Byte_Ptr data) +{ + size_t bytes_read; + size_t len = (size_t)ULEB128(data, bytes_read); + + if (len == 0){ + cerr << "badly formed extended line op encountered!\n"; + // a length of 0 indicates a badly formed op and will force everything to be ignored until 'end_of_sequence'. + return 0; + } + + len += bytes_read; + unsigned char op_code = *data++; + switch (op_code){ + case DW_LNE_end_sequence: + break; + case DW_LNE_set_address: { + size_t size = len - bytes_read - 1; + LinearAddr addr = GetValue(data, size); + LinearAddr relocatedAddress = aPair.iXIPFileDetails.Relocate(addr); + if (addr != relocatedAddress) + WriteValue(data, relocatedAddress, size); + break; + } + case DW_LNE_define_file: + ULEB128(data, bytes_read); + ULEB128(data, bytes_read); + ULEB128(data, bytes_read); + break; + default: + + break; + } + + return len; +} + +void DwarfLineManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){ + Dwarf_Byte_Ptr start = aStart; + Dwarf_Byte_Ptr end = aEnd; + size_t bytes_read = 0; + while (start < end){ + Dwarf_Byte_Ptr hdrptr = start; + size_t offset_size, initial_length_size; + + Dwarf_Word length = READ_UNALIGNED4(hdrptr); + hdrptr += 4; + + if (length >= 0xfffffff0u) { + cerr << "Error: 64 bit DWARF not supported\n"; + exit(EXIT_FAILURE); + } else { + offset_size = 4; + initial_length_size = 4; + } + + Dwarf_Byte_Ptr end_of_sequence = start + length + initial_length_size; + + Dwarf_Half version = READ_UNALIGNED2(hdrptr); + hdrptr += 2; + + if (version != 2 && version != 3){ + static bool warned = false; + if (!warned){ + cerr << "Only DWARF 2 and 3 aranges are currently supported\n"; + warned = true; + } + return; + } + + hdrptr += offset_size; +#if 0 + // Don't need the next four fields + Dwarf_Ubyte min_insn_length = *hdrptr++; + Dwarf_Ubyte default_is_stmt = *hdrptr++; + Dwarf_Ubyte line_base = *hdrptr++; + Dwarf_Ubyte line_range = *hdrptr++; +#endif + hdrptr +=4; + Dwarf_Ubyte opcode_base = *hdrptr++; + + /* Skip the contents of the Opcodes table. */ + Dwarf_Byte_Ptr standard_opcodes = hdrptr; + start = standard_opcodes + opcode_base - 1; + + /* skip the contents of the Directory table. */ + while (*start != 0){ + start += strlen ((char *) start) + 1; + } + /* Skip the NUL at the end of the table. */ + start++; + + /* skip the contents of the File Name table. */ + while (*start != 0){ + start += strlen ((char *) start) + 1; + + ULEB128(start, bytes_read); + ULEB128(start, bytes_read); + ULEB128(start, bytes_read); + } + /* Skip the NUL at the end of the table. */ + start++; + + while (start < end_of_sequence){ + unsigned char op_code = *start++; + + if (op_code >= opcode_base){ + continue; + } else { + switch (op_code){ +// missing from dwarf.h - first byte of extended op codes is '0x0' +#define DW_LNS_extended_op 0x0 + case DW_LNS_extended_op: + size_t n = process_extended_line_op (aPair, start); + // if we don't understand the extended op skip to the end of the sequence :-( + if (n == 0) + start = end_of_sequence; + else + start += n; + break; + + case DW_LNS_copy: + break; + + case DW_LNS_advance_pc: + case DW_LNS_advance_line: + case DW_LNS_set_file: + case DW_LNS_set_column: + ULEB128(start, bytes_read); + break; + + case DW_LNS_negate_stmt: + case DW_LNS_set_basic_block: + case DW_LNS_const_add_pc: + break; + + case DW_LNS_fixed_advance_pc: + start += 2; + break; + + case DW_LNS_set_prologue_end: + case DW_LNS_set_epilogue_begin: + break; + + case DW_LNS_set_isa: + ULEB128(start, bytes_read); + break; + + default: + for (int i = standard_opcodes[op_code - 1]; i > 0 ; --i){ + ULEB128(start, bytes_read); + } + break; + } + } + } + // !! eek ARM seems to require header word aligned - at least for Dwarf 2 + if (aPair.iXIPFileDetails.iRVCTProduced && (version == 2)) + start = (Dwarf_Byte_Ptr)(((unsigned long)start + 3) & ~3); + } +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/dwarflocexpr.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/dwarflocexpr.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,271 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include "dwarfmanager.h" + +void EditLocationExpression (Dwarf_Byte_Ptr data, unsigned int pointer_size, unsigned long length, FileShdrPair & aPair) +{ + unsigned op; + size_t bytes_read; + Dwarf_Byte_Ptr end = data + length; + + while (data < end){ + op = *data++; + + switch (op){ + case DW_OP_addr: + LinearAddr addr = READ_UNALIGNED4(data); + LinearAddr relocatedAddr = aPair.iXIPFileDetails.Relocate(addr); + WRITE_UNALIGNED4(data, relocatedAddr); + data += pointer_size; + break; + case DW_OP_deref: + break; + case DW_OP_const1u: + case DW_OP_const1s: + data++; + break; + case DW_OP_const2u: + case DW_OP_const2s: + data += 2; + break; + case DW_OP_const4u: + case DW_OP_const4s: + data += 4; + break; + case DW_OP_const8u: + case DW_OP_const8s: + data += 8; + break; + case DW_OP_constu: + case DW_OP_consts: + { + ULEB128(data, bytes_read); + break; + } + case DW_OP_dup: + case DW_OP_drop: + case DW_OP_over: + break; + case DW_OP_pick: + data++; + break; + case DW_OP_swap: + case DW_OP_rot: + case DW_OP_xderef: + case DW_OP_abs: + case DW_OP_and: + case DW_OP_div: + case DW_OP_minus: + case DW_OP_mod: + case DW_OP_mul: + case DW_OP_neg: + case DW_OP_not: + case DW_OP_or: + case DW_OP_plus: + break; + case DW_OP_plus_uconst: + { + ULEB128(data, bytes_read); + break; + } + case DW_OP_shl: + case DW_OP_shr: + case DW_OP_shra: + case DW_OP_xor: + break; + case DW_OP_bra: + data += 2; + break; + case DW_OP_eq: + case DW_OP_ge: + case DW_OP_gt: + case DW_OP_le: + case DW_OP_lt: + case DW_OP_ne: + break; + case DW_OP_skip: + data += 2; + break; + + case DW_OP_lit0: + case DW_OP_lit1: + case DW_OP_lit2: + case DW_OP_lit3: + case DW_OP_lit4: + case DW_OP_lit5: + case DW_OP_lit6: + case DW_OP_lit7: + case DW_OP_lit8: + case DW_OP_lit9: + case DW_OP_lit10: + case DW_OP_lit11: + case DW_OP_lit12: + case DW_OP_lit13: + case DW_OP_lit14: + case DW_OP_lit15: + case DW_OP_lit16: + case DW_OP_lit17: + case DW_OP_lit18: + case DW_OP_lit19: + case DW_OP_lit20: + case DW_OP_lit21: + case DW_OP_lit22: + case DW_OP_lit23: + case DW_OP_lit24: + case DW_OP_lit25: + case DW_OP_lit26: + case DW_OP_lit27: + case DW_OP_lit28: + case DW_OP_lit29: + case DW_OP_lit30: + case DW_OP_lit31: + break; + + case DW_OP_reg0: + case DW_OP_reg1: + case DW_OP_reg2: + case DW_OP_reg3: + case DW_OP_reg4: + case DW_OP_reg5: + case DW_OP_reg6: + case DW_OP_reg7: + case DW_OP_reg8: + case DW_OP_reg9: + case DW_OP_reg10: + case DW_OP_reg11: + case DW_OP_reg12: + case DW_OP_reg13: + case DW_OP_reg14: + case DW_OP_reg15: + case DW_OP_reg16: + case DW_OP_reg17: + case DW_OP_reg18: + case DW_OP_reg19: + case DW_OP_reg20: + case DW_OP_reg21: + case DW_OP_reg22: + case DW_OP_reg23: + case DW_OP_reg24: + case DW_OP_reg25: + case DW_OP_reg26: + case DW_OP_reg27: + case DW_OP_reg28: + case DW_OP_reg29: + case DW_OP_reg30: + case DW_OP_reg31: + break; + + case DW_OP_breg0: + case DW_OP_breg1: + case DW_OP_breg2: + case DW_OP_breg3: + case DW_OP_breg4: + case DW_OP_breg5: + case DW_OP_breg6: + case DW_OP_breg7: + case DW_OP_breg8: + case DW_OP_breg9: + case DW_OP_breg10: + case DW_OP_breg11: + case DW_OP_breg12: + case DW_OP_breg13: + case DW_OP_breg14: + case DW_OP_breg15: + case DW_OP_breg16: + case DW_OP_breg17: + case DW_OP_breg18: + case DW_OP_breg19: + case DW_OP_breg20: + case DW_OP_breg21: + case DW_OP_breg22: + case DW_OP_breg23: + case DW_OP_breg24: + case DW_OP_breg25: + case DW_OP_breg26: + case DW_OP_breg27: + case DW_OP_breg28: + case DW_OP_breg29: + case DW_OP_breg30: + case DW_OP_breg31: + case DW_OP_fbreg: + { + ULEB128(data, bytes_read); + break; + } + case DW_OP_bregx: + { + ULEB128(data, bytes_read); + ULEB128(data, bytes_read); + break; + } + case DW_OP_piece: + { + ULEB128(data, bytes_read); + break; + } + case DW_OP_deref_size: + case DW_OP_xderef_size: + data++; + break; + case DW_OP_nop: + /* DWARF 3 extensions. */ + case DW_OP_push_object_address: + break; + case DW_OP_call2: + /* XXX: Strictly speaking for 64-bit DWARF3 files + this ought to be an 8-byte wide computation. */ + data += 2; + break; + case DW_OP_call4: + /* XXX: Strictly speaking for 64-bit DWARF3 files + this ought to be an 8-byte wide computation. */ + data += 4; + break; + case DW_OP_call_ref: + /* XXX: Strictly speaking for 64-bit DWARF3 files + this ought to be an 8-byte wide computation. */ + data += 4; + break; + case DW_OP_form_tls_address: + case DW_OP_call_frame_cfa: + break; + case DW_OP_bit_piece: + { + // Handily the spec doesn't describe the operands - but by analogy with + // DW_OP_piece we assume these are ULEB128 encoded. + ULEB128(data, bytes_read); + ULEB128(data, bytes_read); + break; + } + + /* GNU extensions. */ + case DW_OP_GNU_push_tls_address: + //case DW_OP_GNU_uninit: + /* FIXME: Is there data associated with this OP ? */ + break; + + default: + // bail - can't do anything else sensible here + cerr << "Warning: Unrecognized opcode " << op << " in Dwarf expression.\n"; + return; + } + + } +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/dwarflocmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/dwarflocmanager.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include "dwarfmanager.h" +#include "inputfile.h" + +const string DwarfLocManager::iLocSectionName(".debug_loc"); + +void DwarfLocManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){ + Dwarf_Byte_Ptr start = aStart; + Dwarf_Byte_Ptr end = aEnd; + size_t pointer_size = iDwarfInfoManager.GetPointerSize(); + while (start < end){ + // TODO: this doesn't deal with 64-bit Dwarf + Dwarf_Byte_Ptr lower = start; + Dwarf_Word w1 = GetValue(start, pointer_size); + start+= pointer_size; + Dwarf_Byte_Ptr upper = start; + Dwarf_Word w2 = GetValue(start, pointer_size); + start+= pointer_size; + + if (w1 == 0 && w2 == 0){ + continue; + } + if (w1 == 0xffffffff){ + LinearAddr addr = w2; + LinearAddr relocatedAddress = aPair.iXIPFileDetails.Relocate(addr); + if (addr != relocatedAddress) + WriteValue(start - pointer_size, relocatedAddress, pointer_size); + continue; + } + + if (aPair.iXIPFileDetails.iGCCProduced){ + LinearAddr addr = w1; + LinearAddr relocatedAddress = aPair.iXIPFileDetails.Relocate(addr); + if (addr != relocatedAddress) + WriteValue(lower, relocatedAddress, pointer_size); + addr = w2; + relocatedAddress = aPair.iXIPFileDetails.Relocate(addr); + if (addr != relocatedAddress) + WriteValue(upper, relocatedAddress, pointer_size); + } + + Dwarf_Half length = GetValue(start, 2); + start += 2; + EditLocationExpression (start, pointer_size, length, aPair); + start += length; + + } +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/dwarfmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/dwarfmanager.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,436 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include + +#include "dwarfmanager.h" +#include "inputfile.h" +#include "outputfile.h" +#include "filefragment.h" + +void DwarfSectionManager::AddSection(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr){ + if (iRomDetails->iTrace){ + cout << " " << GetSectionName() << " - DWARF\n"; + } + + FileShdrPair aFileShdrPair(aXIPFileDetails, aShdr); + iFileShdrList.push_back(aFileShdrPair); +} + +void DwarfSectionManager::SetupSection(){ + if (!iFileShdrList.empty()){ + ElfSectionElfData * aDwarfSectionData = new ElfSectionElfData(*this); + Elf32_Shdr aDwarfShdr; + aDwarfShdr.sh_name = 0; // for now. + aDwarfShdr.sh_type = SHT_PROGBITS; + aDwarfShdr.sh_flags = 0; + aDwarfShdr.sh_addr = 0; + aDwarfShdr.sh_offset = 0; // for now + aDwarfShdr.sh_size = 0; // for now. + aDwarfShdr.sh_link = 0; + aDwarfShdr.sh_info = 0; + aDwarfShdr.sh_addralign = 4; + aDwarfShdr.sh_entsize = sizeof(Elf32_Sym); + + ElfSection aDwarfSection(aDwarfSectionData, GetSectionName().c_str(), aDwarfShdr); + iElfSectionManager.AddSection(aDwarfSection); + } +} + +Dwarf_Unsigned DwarfSectionManager::DecodeUnsignedLeb128(Dwarf_Byte_Ptr leb128, size_t & leb128_length){ + Dwarf_Ubyte byte; + Dwarf_Word word_number; + Dwarf_Unsigned number; + Dwarf_Sword shift; + Dwarf_Sword byte_length; + + /* The following unrolls-the-loop for the first few bytes and + unpacks into 32 bits to make this as fast as possible. + word_number is assumed big enough that the shift has a defined + result. */ + if ((*leb128 & 0x80) == 0) { + leb128_length = 1; + return *leb128; + } else if ((*(leb128 + 1) & 0x80) == 0) { + leb128_length = 2; + + word_number = *leb128 & 0x7f; + word_number |= (*(leb128 + 1) & 0x7f) << 7; + return word_number; + } else if ((*(leb128 + 2) & 0x80) == 0) { + leb128_length = 3; + + word_number = *leb128 & 0x7f; + word_number |= (*(leb128 + 1) & 0x7f) << 7; + word_number |= (*(leb128 + 2) & 0x7f) << 14; + return word_number; + } else if ((*(leb128 + 3) & 0x80) == 0) { + leb128_length = 4; + + word_number = *leb128 & 0x7f; + word_number |= (*(leb128 + 1) & 0x7f) << 7; + word_number |= (*(leb128 + 2) & 0x7f) << 14; + word_number |= (*(leb128 + 3) & 0x7f) << 21; + return word_number; + } + + /* The rest handles long numbers Because the 'number' may be larger + than the default int/unsigned, we must cast the 'byte' before + the shift for the shift to have a defined result. */ + number = 0; + shift = 0; + byte_length = 1; + byte = *(leb128); + for (;;) { + number |= ((Dwarf_Unsigned) (byte & 0x7f)) << shift; + + if ((byte & 0x80) == 0) { + leb128_length = byte_length; + return number; + } + shift += 7; + + byte_length++; + ++leb128; + byte = *leb128; + } +} + +#define BITSINBYTE 8 +Dwarf_Signed DwarfSectionManager::DecodeSignedLeb128(Dwarf_Byte_Ptr leb128, size_t & leb128_length){ + Dwarf_Signed number = 0; + Dwarf_Bool sign = 0; + Dwarf_Word shift = 0; + Dwarf_Ubyte byte = *leb128; + Dwarf_Word byte_length = 1; + + /* byte_length being the number of bytes of data absorbed so far in + turning the leb into a Dwarf_Signed. */ + + for (;;) { + sign = byte & 0x40; + number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift; + shift += 7; + + if ((byte & 0x80) == 0) { + break; + } + ++leb128; + byte = *leb128; + byte_length++; + } + + if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) { + number |= -((Dwarf_Signed) 1 << shift); + } + + leb128_length = byte_length; + return number; +} + +Dwarf_Byte_Ptr DwarfSectionManager::GetSectionData(FileShdrPair & aPair){ + + InputFile in(aPair.iXIPFileDetails.iElfFile); + in.SetOffset(aPair.iShdr.sh_offset); + return (Dwarf_Byte_Ptr)in.GetData(aPair.iShdr.sh_size); +} + +void DwarfConcatenatedSectionManager::GetFileFragmentData(FileFragmentData & aFileFragmentData ){ + ConcatenateData(); + if (iRomDetails->iTrace){ + cout << "\nGenerating DWARF section " << GetSectionName() << " size = " + << dec << Size() << " bytes\n"; + } + FileShdrList::iterator e = iFileShdrList.end(); + for (FileShdrList::iterator i = iFileShdrList.begin(); i < e; i++){ + if (iRomDetails->iTrace){ + cout << " " << i->iXIPFileDetails.iElfFile << " " << dec << i->iShdr.sh_size << " bytes\n" << flush; + } + ProcessSection(*i); + } + SetFileFragmentData(aFileFragmentData, iSize, reinterpret_cast(iData)); +} + +void DwarfConcatenatedSectionManager::ConcatenateData(){ + if (iData == NULL) { + size_t sectionSize = Size(); + iData = new Dwarf_Ubyte[sectionSize]; + Dwarf_Byte_Ptr p = iData; + FileShdrList::iterator e = iFileShdrList.end(); + for (FileShdrList::iterator i = iFileShdrList.begin(); i < e; i++){ + size_t off = p - iData; + size_t soff = GetSectionOffset(i->iXIPFileDetails.iElfFile); + if (off >= sectionSize) + assert(off < sectionSize); + if (off != soff) + assert(off == soff); + size_t n = i->iShdr.sh_size; + Dwarf_Byte_Ptr contrib = GetSectionData(*i); + memcpy(p, contrib, n); + p += n; + delete [] contrib; + } + } +} + +size_t DwarfConcatenatedSectionManager::Size(){ + if (iSizeValid) + return iSize; + //cerr << "Size for " << GetSectionName() << "\n"; + size_t offset = 0; + FileShdrList::iterator e = iFileShdrList.end(); + for (FileShdrList::iterator i = iFileShdrList.begin(); i != e; i++){ + //cerr << "offset = 0x" << offset << "\t"; + SetSectionOffset(i->iXIPFileDetails.iElfFile, offset); + size_t size = i->iShdr.sh_size; + //cerr << "section size for " << i->iXIPFileDetails.iElfFile << " 0x" << size << "\n"; + SetSectionSize(i->iXIPFileDetails.iElfFile, size); + size_t newOffset = offset + size; + if (newOffset < offset){ + cerr << "Error: The combined section " << GetSectionName() + << " requires translation from 32 to 64 bit Dwarf which is not currently supported.\n" + << "Exclude the following files (or their equivalent in terms of their contribution to Dwarf):\n"; + for (; i != e; i++){ + cerr << i->iXIPFileDetails.iE32File << "\n"; + } + exit(EXIT_FAILURE); + } + offset = newOffset; + } + //cerr << "Size = 0x" << offset << "\n"; + iSizeValid = true; + return iSize = offset; +} + +void DwarfConcatenatedSectionManager::ProcessSection(FileShdrPair & aPair){ + Dwarf_Byte_Ptr start = GetSection(aPair.iXIPFileDetails.iElfFile); + Dwarf_Byte_Ptr end = start + aPair.iShdr.sh_size; + ProcessSection(aPair, start, end); +} + +void DwarfConcatenatedSectionManager::SetSectionOffset(PathName & aPathName, size_t aOffset) { + iPathNameSectionOffsetMap[aPathName] = aOffset; +} + +void DwarfConcatenatedSectionManager::InitOffsetMap(){ + Size(); // forces the map to be set up if it hasn't been already +} + +size_t DwarfConcatenatedSectionManager::GetSectionOffset(PathName & aPathName){ + if (!iSizeValid) // if the size is valid then so must be the offsets. + InitOffsetMap(); + return iPathNameSectionOffsetMap[aPathName]; +} + +void DwarfConcatenatedSectionManager::SetSectionSize(PathName & aPathName, size_t aSize) { + iPathNameSectionSizeMap[aPathName] = aSize; +} + +size_t DwarfConcatenatedSectionManager::GetSectionSize(PathName & aPathName){ + if (!iSizeValid) // if the size is valid then so must be the offsets. + InitOffsetMap(); + return iPathNameSectionSizeMap[aPathName]; +} + +Dwarf_Byte_Ptr DwarfConcatenatedSectionManager::GetSection(PathName & aPathName){ + ConcatenateData(); + size_t offset = GetSectionOffset(aPathName); + return iData + offset; +} + +class ElfSectionFragmentedDwarfData : public ElfSectionElfData { +public: + ElfSectionFragmentedDwarfData(FileFragmentOwner & aSource) : + ElfSectionElfData(aSource) + {} + + ElfSectionFragmentedDwarfData(const ElfSectionElfData & aData) : + ElfSectionElfData(aData) + {} + + // ElfSection protocol + virtual ElfSectionFragmentedDwarfData * Clone(){ + return new ElfSectionFragmentedDwarfData(*this); + } + + virtual void AddData(OutputFile & aOutputFile){ + return; + } +}; + +class DwarfSectionFragment : public FileFragmentOwner { +public: + DwarfSectionFragment(DwarfFragmentedSectionManager & aSource, + FileShdrPair & aPair): + iSource(aSource), + iPair(aPair), + iData(NULL) + {} + + // Bitwise copy is OK so don't need to write our own copy ctor etc. + + // The FileFragmentOwner protocol + virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ); + virtual size_t Size(); + virtual void DeleteFileFragmentData(); + +private: + DwarfSectionFragment(); + +private: + DwarfFragmentedSectionManager & iSource; + FileShdrPair & iPair; + Dwarf_Byte_Ptr iData; +}; + +void DwarfSectionFragment::GetFileFragmentData(FileFragmentData & aFileFragmentData ){ + iSource.ProcessSection(iPair, iData); + SetFileFragmentData(aFileFragmentData, Size(), reinterpret_cast(iData)); +} + +size_t DwarfSectionFragment::Size(){ + return iPair.iShdr.sh_size; +} + +void DwarfSectionFragment::DeleteFileFragmentData(){ + delete [] iData; + // + delete this; +} + +void DwarfFragmentedSectionManager::SetupSection(){ + if (!iFileShdrList.empty()){ + ElfSectionFragmentedDwarfData * aDwarfSectionData = new ElfSectionFragmentedDwarfData(*this); + Elf32_Shdr aDwarfShdr; + aDwarfShdr.sh_name = 0; // for now. + aDwarfShdr.sh_type = SHT_PROGBITS; + aDwarfShdr.sh_flags = 0; + aDwarfShdr.sh_addr = 0; + aDwarfShdr.sh_offset = 0; // for now + aDwarfShdr.sh_size = 0; // for now. + aDwarfShdr.sh_link = 0; + aDwarfShdr.sh_info = 0; + aDwarfShdr.sh_addralign = 4; + aDwarfShdr.sh_entsize = sizeof(Elf32_Sym); + + // aDwarfSectionData will ask the secton manager (i.e. its source) for the offset of the section. + // So we better record it here. We assume that it is the current size of the output file. + // As long as we are single threaded and all the fragments get added consecutively as below + // this is a safe assumption. + SetOffset(iDwarfManager.GetOutputFile().Size()); + + ElfSection aDwarfSection(aDwarfSectionData, GetSectionName().c_str(), aDwarfShdr); + iElfSectionManager.AddSection(aDwarfSection); + + for (FileShdrList::iterator i = iFileShdrList.begin(); i < iFileShdrList.end(); i++ ){ + DwarfSectionFragment * aFrag = new DwarfSectionFragment(*this, *i); + aFrag->AddData(iDwarfManager.GetOutputFile()); + } + } +} + +// NB the section itself doesn't write any data +// The FileFragmentOwner protocol + +void DwarfFragmentedSectionManager::GetFileFragmentData(FileFragmentData & aFileFragmentData ){ + SetFileFragmentData(aFileFragmentData, 0, reinterpret_cast(NULL)); +} + +// This should never get called +void DwarfFragmentedSectionManager::ConcatenateData(){ + assert(1 == 0); + return; +} + +void DwarfFragmentedSectionManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr & aData){ + if (iInitialTraceMessage & iRomDetails->iTrace){ + cout << "\nGenerating DWARF section " << GetSectionName() << " size = " + << dec << Size() << " bytes\n"; + iInitialTraceMessage = false; + } + if (iRomDetails->iTrace){ + cout << " " << aPair.iXIPFileDetails.iElfFile << " size = " + << dec << aPair.iShdr.sh_size << "\n" << flush; + } + Dwarf_Byte_Ptr start = GetSectionData(aPair); + aData = start; + Dwarf_Byte_Ptr end = start + aPair.iShdr.sh_size; + ProcessSection(aPair, start, end); +} + +#if 0 +// This should never get called +void DwarfFragmentedSectionManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end){ + assert(1 == 0); + return; +} +#endif + +const string DwarfMacinfoManager::iMacinfoSectionName(".debug_macinfo"); +const string DwarfStrManager::iStrSectionName(".debug_str"); + + +void DwarfManager::AddSection(XIPFileDetails & aXIPFileDetails, string aSectionName, Elf32_Shdr * aShdr){ + if (iDwarfAbbrevManager.GetSectionName() == aSectionName) + iDwarfAbbrevManager.AddSection(aXIPFileDetails, aShdr); + else if (iDwarfArangesManager.GetSectionName() == aSectionName) + iDwarfArangesManager.AddSection(aXIPFileDetails, aShdr); + else if (iDwarfFrameManager.GetSectionName() == aSectionName) + iDwarfFrameManager.AddSection(aXIPFileDetails, aShdr); + else if (iDwarfInfoManager.GetSectionName() == aSectionName) + iDwarfInfoManager.AddSection(aXIPFileDetails, aShdr); + else if (iDwarfLineManager.GetSectionName() == aSectionName) + iDwarfLineManager.AddSection(aXIPFileDetails, aShdr); + else if (iDwarfLocManager.GetSectionName() == aSectionName) + iDwarfLocManager.AddSection(aXIPFileDetails, aShdr); + else if (iDwarfMacinfoManager.GetSectionName() == aSectionName) + iDwarfMacinfoManager.AddSection(aXIPFileDetails, aShdr); + else if (iDwarfPubnamesManager.GetSectionName() == aSectionName) + iDwarfPubnamesManager.AddSection(aXIPFileDetails, aShdr); + else if (iDwarfPubtypesManager.GetSectionName() == aSectionName) + iDwarfPubtypesManager.AddSection(aXIPFileDetails, aShdr); + else if (iDwarfRangesManager.GetSectionName() == aSectionName) + iDwarfRangesManager.AddSection(aXIPFileDetails, aShdr); + else if (iDwarfStrManager.GetSectionName() == aSectionName) + iDwarfStrManager.AddSection(aXIPFileDetails, aShdr); +#if 0 + else + cerr << "Warning: unrecognised debug section name " << aSectionName << " ignored\n"; +#endif +} + +void DwarfManager::SetupSections(){ + // The order here is important for fix up + // first the purely concatenated 'leaf' sections + // See the diagram on p.182 of the Dwarf 3 spec + // to understand the 'dependenices' + iDwarfAbbrevManager.SetupSection(); + iDwarfFrameManager.SetupSection(); + iDwarfPubnamesManager.SetupSection(); + iDwarfPubtypesManager.SetupSection(); + iDwarfArangesManager.SetupSection(); + iDwarfMacinfoManager.SetupSection(); + + iDwarfInfoManager.SetupSection(); + iDwarfLineManager.SetupSection(); + iDwarfLocManager.SetupSection(); + + iDwarfRangesManager.SetupSection(); + iDwarfStrManager.SetupSection(); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/dwarfmanager.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/dwarfmanager.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,699 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef DWARFMANAGER_H_ +#define DWARFMANAGER_H_ + +#include +#include +#include +#include + +#include "dwarfdefs.h" +#include "dwarf.h" +#include "defs.h" +#include "filefragment.h" +#include "romdetails.h" +#include "elfsectionmanager.h" + +using namespace std; + +class FileShdrPair { +public: + FileShdrPair(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr): + iXIPFileDetails(aXIPFileDetails), + iShdr(*aShdr) + {} + FileShdrPair & FileShdrPair::operator=(const FileShdrPair & aFileShdrPair) { + iXIPFileDetails = aFileShdrPair.iXIPFileDetails; + iShdr = aFileShdrPair.iShdr; + return *this; + } + + FileShdrPair::FileShdrPair(const FileShdrPair &aFileShdrPair): + iXIPFileDetails(aFileShdrPair.iXIPFileDetails), + iShdr(aFileShdrPair.iShdr) + {} + + XIPFileDetails & iXIPFileDetails; + Elf32_Shdr iShdr; +}; + +typedef std::vector FileShdrList; + +void EditLocationExpression (Dwarf_Byte_Ptr data, + unsigned int pointer_size, + unsigned long length, + FileShdrPair & aPair); +class DwarfManager; + +class DwarfSectionManager : public FileFragmentOwner { +public: + DwarfSectionManager(ElfSectionManager & aElfSectionManager, + DwarfManager & aDwarfManager, + const string & aName, + RomDetails * aRomDetails): + iElfSectionManager(aElfSectionManager), + iDwarfManager(aDwarfManager), + iSectionName(aName), + iSizeValid(false), + iSize(0), + iData(NULL), + iRomDetails(aRomDetails) + {} + + virtual ~DwarfSectionManager() { + iFileShdrList.clear(); + } + + // The FileFragmentOwner protocol + virtual void DeleteFileFragmentData(){ + if (iData) { + Dwarf_Byte_Ptr d = iData; + iData = NULL; + delete [] d; + } + } + + virtual void AddSection(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr); + virtual void SetupSection(); + const string & GetSectionName() { return iSectionName; } + virtual Dwarf_Byte_Ptr GetSectionData(FileShdrPair & aPair); + + + + // LEB decoding + // Leb128 decoding used by all Dwarf section managers (potentially) + // TODO could get rid of LEB macros and define as inline functions. +#define DECODE_ULEB128(v,p,n) \ + Dwarf_Word v = DwarfSectionManager::DecodeUnsignedLeb128(p, n);\ + p += n; +#define ULEB128(p,n) \ + DwarfSectionManager::DecodeUnsignedLeb128(p, n);\ + p += n; + static Dwarf_Unsigned DecodeUnsignedLeb128(Dwarf_Byte_Ptr leb128, size_t & leb128_length); +#define DECODE_SLEB128(v,p,n) \ + Dwarf_Word v = DwarfSectionManager::DecodeSignedLeb128(p, n);\ + p += n; +#define SLEB128(p,n) \ + DwarfSectionManager::DecodeSignedLeb128(p, n);\ + p += n; + static Dwarf_Signed DecodeSignedLeb128(Dwarf_Byte_Ptr leb128, size_t & leb128_length); + +private: + // Don't want one of these to be copied + DwarfSectionManager(const DwarfSectionManager & aDwarfSectionManager); + + DwarfSectionManager & operator=(const DwarfSectionManager & aDwarfSectionManager); +protected: + + virtual Dwarf_Byte_Ptr GetData(){ return iData; } + virtual void SetData(Dwarf_Byte_Ptr data) { iData = data; } + + size_t CheckNewOffset(size_t base, size_t offset){ + const Dwarf_Off limit = 0xfffffff0ul; + Dwarf_Off newOffset = base + offset; + if (newOffset >= limit) { + cerr << "Error: cannot support transition from 32 to 64 bit offsets\n"; + exit(EXIT_FAILURE); + } + return (size_t)newOffset; + } + +protected: + ElfSectionManager & iElfSectionManager; + DwarfManager & iDwarfManager; + FileShdrList iFileShdrList; + const string iSectionName; + bool iSizeValid; + size_t iSize; + Dwarf_Byte_Ptr iData; + RomDetails * iRomDetails; +}; + +class DwarfConcatenatedSectionManager : public DwarfSectionManager { +public: + DwarfConcatenatedSectionManager(ElfSectionManager & aElfSectionManager, + DwarfManager & aDwarfManager, + const string & aName, + RomDetails * aRomDetails): + DwarfSectionManager(aElfSectionManager, + aDwarfManager, + aName, + aRomDetails) + {} + + // The FileFragmentOwner protocol + virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ); + virtual size_t Size(); + + virtual void ConcatenateData(); + virtual void ProcessSection(FileShdrPair & aPair); + virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end){}; + + // Concatenated section protocol + virtual void SetSectionOffset(PathName & aPathName, size_t aOffset); + virtual void InitOffsetMap(); + virtual size_t GetSectionOffset(PathName & aPathName); + virtual void SetSectionSize(PathName & aPathName, size_t aSize); + virtual size_t GetSectionSize(PathName & aPathName); + + Dwarf_Byte_Ptr GetSection(PathName & aPathName); + +protected: + typedef std::map PathNameSectionOffsetMap; + PathNameSectionOffsetMap iPathNameSectionOffsetMap; + PathNameSectionOffsetMap iPathNameSectionSizeMap; + + +}; + +class DwarfFragmentedSectionManager : public DwarfConcatenatedSectionManager { +public: + DwarfFragmentedSectionManager(ElfSectionManager & aElfSectionManager, + DwarfManager & aDwarfManager, + const string & aName, + RomDetails * aRomDetails): + DwarfConcatenatedSectionManager(aElfSectionManager, + aDwarfManager, + aName, + aRomDetails), + iInitialTraceMessage(true) + {} + + // Override the method of setting up the section + virtual void SetupSection(); + + // The FileFragmentOwner protocol + virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ); + //virtual size_t Size(); + + virtual void ConcatenateData(); + + void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr & aData); + virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end) = 0; + +private: + bool iInitialTraceMessage; + +}; + +class DebugAbbrevAttrForm { +public: + DebugAbbrevAttrForm(): + iAttr(0), + iForm(0) + {} + DebugAbbrevAttrForm(Dwarf_Half a, Dwarf_Half f): + iAttr(a), + iForm(f) + {} + Dwarf_Half iAttr; + Dwarf_Half iForm; +}; + +class DebugAbbrev { +public: + DebugAbbrev(): + iCode(0), + iTag(0), + iCount(0), + iRaw(NULL), + iParsed(NULL) + {} + DebugAbbrev(Dwarf_Unsigned c, Dwarf_Unsigned t, size_t n, Dwarf_Byte_Ptr r, DebugAbbrevAttrForm * p): + iCode(c), + iTag(t), + iCount(n), + iRaw(r), + iParsed(p) + {} + DebugAbbrev & operator=(const DebugAbbrev & aDebugAbbrev){ + iCode = aDebugAbbrev.iCode; + iTag = aDebugAbbrev.iTag; + iCount = aDebugAbbrev.iCount; + iRaw = aDebugAbbrev.iRaw; + iParsed = aDebugAbbrev.iParsed; + return *this; + } + + DebugAbbrev(const DebugAbbrev & aDebugAbbrev){ + *this = aDebugAbbrev; + } + + void Destroy(){ + if (iParsed){ + DebugAbbrevAttrForm * d = iParsed; + iParsed = NULL; + delete [] d; + } + } +#if 0 + // can't have default dtor do anything until and unless we prevent iParsed getting deleted + // whenever the class is copied in STL containers. + ~DebugAbbrev(){ + if (iParsed){ + DebugAbbrevAttrForm * d = iParsed; + iParsed = NULL; + delete [] d; + } + } +#endif + Dwarf_Unsigned iCode; + Dwarf_Unsigned iTag; + size_t iCount; + Dwarf_Byte_Ptr iRaw; + DebugAbbrevAttrForm * iParsed; +}; + +class InfoContext { +private: + typedef std::map AbbrevMap; + class AbbrevMapEntry { + public: + AbbrevMapEntry(): + iCursor(NULL), + iMap(NULL) + {} + AbbrevMapEntry(Dwarf_Byte_Ptr c, AbbrevMap * m): + iCursor(c), + iMap(m) + {} + Dwarf_Byte_Ptr iCursor; + AbbrevMap * iMap; + }; + typedef std::map AbbrevOffsetMap; + +public: + InfoContext(): + iContextValid(false), + iSectionStart(NULL), + iSectionEnd(NULL), + iSectionOffset(0), + // this is an invalid offset for 32 bit dwarf + // and will trigger the right behaviour in SetAbbrevOffset + // when called from Init + iAbbrevOffset(0xffffffff), + + iAbbrevMapEntry(NULL, NULL) + { + //ClearMap(); + } + ~InfoContext(){ + Reset(); + } + void Init(Dwarf_Byte_Ptr s, Dwarf_Byte_Ptr e, size_t o){ + iSectionStart = s; + iSectionEnd = e; + iSectionOffset = o; + //ClearMap(); + iContextValid = true; + SetAbbrevOffset(0); + } + void Reset(){ + iContextValid = false; + iSectionStart = iSectionEnd = NULL; + iSectionOffset = 0; + iAbbrevOffset = 0xffffffff; + ClearMap(); + } + void ClearMap() { + for (AbbrevOffsetMap::iterator i = iMap.begin(); i != iMap.end(); i++){ + AbbrevMap::iterator e = i->second.iMap->end(); + for (AbbrevMap::iterator b = i->second.iMap->begin(); b != e; b++){ + b->second.Destroy(); + } + i->second.iMap->clear(); + } + iMap.clear(); + } + size_t GetSectionOffset(){ return iSectionOffset; } + + void SetAbbrevOffset(size_t offset); + + DebugAbbrev & GetAbbrev(Dwarf_Word aCode); + DebugAbbrev & FindAbbrev(Dwarf_Word aCode); + + bool iContextValid; + Dwarf_Byte_Ptr iSectionStart; + Dwarf_Byte_Ptr iSectionEnd; + size_t iSectionOffset; + size_t iAbbrevOffset; + AbbrevMapEntry iAbbrevMapEntry; + AbbrevOffsetMap iMap; +}; + +class DwarfAbbrevManager : public DwarfConcatenatedSectionManager { +public: + DwarfAbbrevManager(ElfSectionManager & aElfSectionManager, + DwarfManager & aDwarfManager, + RomDetails * aRomDetails): + DwarfConcatenatedSectionManager(aElfSectionManager, + aDwarfManager, + iAbbrevSectionName, + aRomDetails) + {} + + // we might need to hang onto this after its been written to file + virtual void DeleteFileFragmentData(){} + + void StartContext(PathName & aName); + void EndContext(); + void SetContextAbbrevOffset(Uint32 offset); + size_t GetContextSectionOffset(); + + DebugAbbrev & GetAbbrev(Dwarf_Word aCode); +private: + static const string iAbbrevSectionName; + InfoContext iInfoContext; + +}; + +class DwarfMacinfoManager : public DwarfFragmentedSectionManager { +public: + DwarfMacinfoManager(ElfSectionManager & aElfSectionManager, + DwarfManager & aDwarfManager, + RomDetails * aRomDetails): + DwarfFragmentedSectionManager(aElfSectionManager, + aDwarfManager, + iMacinfoSectionName, + aRomDetails) + {} + virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end){}; + +private: + + static const string iMacinfoSectionName; +}; + +//class DwarfInfoManager : public DwarfConcatenatedSectionManager { +class DwarfInfoManager : public DwarfFragmentedSectionManager { +public: + DwarfInfoManager(ElfSectionManager & aElfSectionManager, + DwarfManager & aDwarfManager, + DwarfAbbrevManager & aDwarfAbbrevManager, + DwarfMacinfoManager & aDwarfMacinfoManager, + RomDetails * aRomDetails): + DwarfFragmentedSectionManager(aElfSectionManager, + aDwarfManager, + iInfoSectionName, + aRomDetails), + iDwarfAbbrevManager(aDwarfAbbrevManager), + iDwarfMacinfoManager(aDwarfMacinfoManager), + iAddressSize(4), + iLocalLength(0) + {} + + virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end); + + size_t GetPointerSize() { return iAddressSize; } + +private: + Dwarf_Byte_Ptr ProcessCU(FileShdrPair & aPair, Dwarf_Byte_Ptr s, Dwarf_Byte_Ptr e); + Dwarf_Byte_Ptr ProcessDIE(FileShdrPair & aPair, Dwarf_Byte_Ptr s, Dwarf_Byte_Ptr e); + + typedef Dwarf_Byte_Ptr (*InfoEditFn)(DwarfInfoManager&, Dwarf_Byte_Ptr, Dwarf_Half,FileShdrPair & aPair); + +#define DECLARE_INFO_EDIT_FN(name)static Dwarf_Byte_Ptr name(DwarfInfoManager& aManager, \ + Dwarf_Byte_Ptr aPtr, \ + Dwarf_Half aForm, \ + FileShdrPair & aPair) + DECLARE_INFO_EDIT_FN(DefaultInfoEditFn); + DECLARE_INFO_EDIT_FN(ErrorInfoEditFn); + DECLARE_INFO_EDIT_FN(InfoEditAddress); + DECLARE_INFO_EDIT_FN(InfoEditLinePtr); + DECLARE_INFO_EDIT_FN(InfoEditLocListPtr); + DECLARE_INFO_EDIT_FN(InfoEditLocExpr); + DECLARE_INFO_EDIT_FN(InfoEditMacInfoPtr); + DECLARE_INFO_EDIT_FN(InfoEditRangeListPtr); + DECLARE_INFO_EDIT_FN(InfoEditString); + DECLARE_INFO_EDIT_FN(InfoEditReference); + DECLARE_INFO_EDIT_FN(InfoEditTrampoline); + + size_t SizeOfDieValue(Dwarf_Half aForm, Dwarf_Byte_Ptr aPtr); + +private: + static const string iInfoSectionName; + DwarfAbbrevManager & iDwarfAbbrevManager; + DwarfMacinfoManager & iDwarfMacinfoManager; + static InfoEditFn iInfoEditFn[]; + + size_t iAddressSize; + size_t iLocalLength; +}; + +class DwarfFrameManager : public DwarfFragmentedSectionManager { +public: + DwarfFrameManager(ElfSectionManager & aElfSectionManager, + DwarfManager & aDwarfManager, + RomDetails * aRomDetails): + DwarfFragmentedSectionManager(aElfSectionManager, + aDwarfManager, + iFrameSectionName, + aRomDetails) + {} + + virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end); + +private: + typedef std::map CiePtrEncodingMap; + typedef std::map CieAugmentationMap; + + static const string iFrameSectionName; +}; + +class DwarfLineManager : public DwarfFragmentedSectionManager { +public: + DwarfLineManager(ElfSectionManager & aElfSectionManager, + DwarfManager & aDwarfManager, + DwarfInfoManager & aDwarfInfoManager, + RomDetails * aRomDetails): + DwarfFragmentedSectionManager(aElfSectionManager, + aDwarfManager, + iLineSectionName, + aRomDetails), + iDwarfInfoManager(aDwarfInfoManager) + {} + + virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end); + +private: + DwarfInfoManager & iDwarfInfoManager; + + static const string iLineSectionName; +}; + +class DwarfLocManager : public DwarfFragmentedSectionManager { +public: + DwarfLocManager(ElfSectionManager & aElfSectionManager, + DwarfManager & aDwarfManager, + DwarfInfoManager & aDwarfInfoManager, + RomDetails * aRomDetails): + DwarfFragmentedSectionManager(aElfSectionManager, + aDwarfManager, + iLocSectionName, + aRomDetails), + iDwarfInfoManager(aDwarfInfoManager) + {} + + virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end); + +private: + DwarfInfoManager & iDwarfInfoManager; + + static const string iLocSectionName; +}; + +class DwarfNameManager : public DwarfFragmentedSectionManager { +public: + DwarfNameManager(ElfSectionManager & aElfSectionManager, + DwarfManager & aDwarfManager, + const string & aName, + DwarfInfoManager & aDwarfInfoManager, + RomDetails * aRomDetails): + DwarfFragmentedSectionManager(aElfSectionManager, + aDwarfManager, + aName, + aRomDetails), + iDwarfInfoManager(aDwarfInfoManager) + {} + + virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end); + +protected: + DwarfInfoManager & iDwarfInfoManager; +}; + +class DwarfPubnamesManager : public DwarfNameManager { +public: + DwarfPubnamesManager(ElfSectionManager & aElfSectionManager, + DwarfManager & aDwarfManager, + DwarfInfoManager & aDwarfInfoManager, + RomDetails * aRomDetails): + DwarfNameManager(aElfSectionManager, + aDwarfManager, + iPubnamesSectionName, + aDwarfInfoManager, + aRomDetails) + {} + +private: + static const string iPubnamesSectionName; +}; + +class DwarfPubtypesManager : public DwarfNameManager { +public: + DwarfPubtypesManager(ElfSectionManager & aElfSectionManager, + DwarfManager & aDwarfManager, + DwarfInfoManager & aDwarfInfoManager, + RomDetails * aRomDetails): + DwarfNameManager(aElfSectionManager, + aDwarfManager, + iPubtypesSectionName, + aDwarfInfoManager, + aRomDetails) + {} + +private: + static const string iPubtypesSectionName; +}; + +class DwarfArangesManager : public DwarfFragmentedSectionManager { +public: + DwarfArangesManager(ElfSectionManager & aElfSectionManager, + DwarfManager & aDwarfManager, + DwarfInfoManager & aDwarfInfoManager, + RomDetails * aRomDetails): + DwarfFragmentedSectionManager(aElfSectionManager, + aDwarfManager, + iArangesSectionName, + aRomDetails), + iDwarfInfoManager(aDwarfInfoManager) + {} + + virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end); + +private: + DwarfInfoManager & iDwarfInfoManager; + + static const string iArangesSectionName; +}; + + +class DwarfRangesManager : public DwarfFragmentedSectionManager { +public: + DwarfRangesManager(ElfSectionManager & aElfSectionManager, + DwarfManager & aDwarfManager, + DwarfInfoManager & aDwarfInfoManager, + RomDetails * aRomDetails): + DwarfFragmentedSectionManager(aElfSectionManager, + aDwarfManager, + iRangesSectionName, + aRomDetails), + iDwarfInfoManager(aDwarfInfoManager) + {} + + virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end); + +private: + DwarfInfoManager & iDwarfInfoManager; + + static const string iRangesSectionName; +}; + +class DwarfStrManager : public DwarfFragmentedSectionManager { +public: + DwarfStrManager(ElfSectionManager & aElfSectionManager, + DwarfManager & aDwarfManager, + RomDetails * aRomDetails): + DwarfFragmentedSectionManager(aElfSectionManager, + aDwarfManager, + iStrSectionName, + aRomDetails) + {} + + virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end){}; + +private: + static const string iStrSectionName; +}; + +class DwarfManager { +public: + DwarfManager(ElfSectionManager & aElfSectionManager, + RomDetails * aRomDetails, + OutputFile & aOutputFile): + iDwarfAbbrevManager(aElfSectionManager, *this, aRomDetails), + iDwarfFrameManager(aElfSectionManager, *this, aRomDetails), + iDwarfMacinfoManager(aElfSectionManager, *this, aRomDetails), + iDwarfInfoManager(aElfSectionManager, *this, iDwarfAbbrevManager, iDwarfMacinfoManager, aRomDetails), + iDwarfLineManager(aElfSectionManager, *this, iDwarfInfoManager, aRomDetails), + iDwarfLocManager(aElfSectionManager, *this, iDwarfInfoManager, aRomDetails), + iDwarfPubnamesManager(aElfSectionManager, *this, iDwarfInfoManager, aRomDetails), + iDwarfPubtypesManager(aElfSectionManager, *this, iDwarfInfoManager, aRomDetails), + iDwarfArangesManager(aElfSectionManager, *this,iDwarfInfoManager, aRomDetails), + iDwarfRangesManager(aElfSectionManager, *this,iDwarfInfoManager, aRomDetails), + iDwarfStrManager(aElfSectionManager, *this, aRomDetails), + iRomDetails(aRomDetails), + iOutputFile(aOutputFile) + {} + + size_t GetLineSectionOffset(PathName & pname){ + return iDwarfLineManager.GetSectionOffset(pname); + } + size_t GetLocListSectionOffset(PathName & pname){ + return iDwarfLocManager.GetSectionOffset(pname); + } + size_t GetMacInfoSectionOffset(PathName & pname){ + return iDwarfMacinfoManager.GetSectionOffset(pname); + } + size_t GetRangesSectionOffset(PathName & pname){ + return iDwarfRangesManager.GetSectionOffset(pname); + } + size_t GetStrSectionOffset(PathName & pname){ + return iDwarfStrManager.GetSectionOffset(pname); + } + + OutputFile & GetOutputFile() { return iOutputFile; } + + void AddSection(XIPFileDetails & aXIPFileDetails, string aSectionName, Elf32_Shdr * aShdr); + void SetupSections(); + +private: + // Don't want one of these to be copied + DwarfManager(const DwarfManager & aDwarfManager); + + DwarfManager & operator=(const DwarfManager & aDwarfManager); + +private: + DwarfAbbrevManager iDwarfAbbrevManager; + DwarfFrameManager iDwarfFrameManager; + DwarfMacinfoManager iDwarfMacinfoManager; + DwarfInfoManager iDwarfInfoManager; + DwarfLineManager iDwarfLineManager; + DwarfLocManager iDwarfLocManager; + DwarfPubnamesManager iDwarfPubnamesManager; + DwarfPubtypesManager iDwarfPubtypesManager; + DwarfArangesManager iDwarfArangesManager; + DwarfRangesManager iDwarfRangesManager; + DwarfStrManager iDwarfStrManager; + RomDetails * iRomDetails; + OutputFile & iOutputFile; +}; + +#endif /*DWARFMANAGER_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/dwarfnamemanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/dwarfnamemanager.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include "dwarfmanager.h" +#include "inputfile.h" + +const string DwarfPubnamesManager::iPubnamesSectionName(".debug_pubnames"); +const string DwarfPubtypesManager::iPubtypesSectionName(".debug_pubtypes"); + +void DwarfNameManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){ + Dwarf_Byte_Ptr start = aStart; + Dwarf_Byte_Ptr end = aEnd; + while (start < end){ + Dwarf_Byte_Ptr data = start; + size_t offset_size, initial_length_size; + + Dwarf_Word length = READ_UNALIGNED4(data); + data += 4; + + if (length >= 0xfffffff0u) { + cerr << "Error: 64 bit DWARF not supported\n"; + exit(EXIT_FAILURE); + } else { + offset_size = 4; + initial_length_size = 4; + } + + Dwarf_Half version = READ_UNALIGNED2(data); + data += 2; + + Dwarf_Word offset = GetValue(data, offset_size); + Dwarf_Word newOffset = CheckNewOffset(iDwarfInfoManager.GetSectionOffset(aPair.iXIPFileDetails.iElfFile), offset); + if (offset != newOffset) + WriteValue(data, offset, offset_size); + data += offset_size; + + + //Dwarf_Word size = GetValue(data, offset_size); + // Don't need the length field + data += offset_size; + + start += length + initial_length_size; + + if (version != 2 && version != 3){ + static bool warned = false; + if (!warned){ + cerr << "Only DWARF 2 and 3 pubnames are currently supported\n"; + warned = true; + } + + continue; + } + + do { + offset = GetValue(data, offset_size); + + if (offset != 0) + { + data += offset_size; + data += strlen ((char *) data) + 1; + } + } + while (offset != 0); + } +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/dwarfrangesmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/dwarfrangesmanager.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include "dwarfmanager.h" +#include "inputfile.h" + +const string DwarfRangesManager::iRangesSectionName(".debug_ranges"); + +void DwarfRangesManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){ + Dwarf_Byte_Ptr start = aStart; + Dwarf_Byte_Ptr end = aEnd; + size_t pointer_size = iDwarfInfoManager.GetPointerSize(); + while (start < end){ + // TODO: this doesn't deal with 64-bit Dwarf + Dwarf_Word w1 = GetValue(start, pointer_size); + start+= pointer_size; + if (w1 == 0xffffffff){ + LinearAddr addr = GetValue(start, pointer_size); + LinearAddr relocatedAddress = aPair.iXIPFileDetails.Relocate(addr); + if (addr != relocatedAddress) + WriteValue(start, relocatedAddress, pointer_size); + } + start += pointer_size; + } +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/dwarfutils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/dwarfutils.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,208 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include "dwarfdefs.h" +#include "dwarf.h" + +char * GetDwarfTag(Dwarf_Unsigned aTag){ + switch (aTag){ + case DW_TAG_array_type: return "DW_TAG_array_type"; + case DW_TAG_class_type: return "DW_TAG_class_type"; + case DW_TAG_entry_point: return "DW_TAG_entry_point"; + case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type"; + case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter"; + case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration"; + case DW_TAG_label: return "DW_TAG_label"; + case DW_TAG_lexical_block: return "DW_TAG_lexical_block"; + case DW_TAG_member: return "DW_TAG_member"; + case DW_TAG_pointer_type: return "DW_TAG_pointer_type"; + case DW_TAG_reference_type: return "DW_TAG_reference_type"; + case DW_TAG_compile_unit: return "DW_TAG_compile_unit"; + case DW_TAG_string_type: return "DW_TAG_string_type"; + case DW_TAG_structure_type: return "DW_TAG_structure_type"; + case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type"; + case DW_TAG_typedef: return "DW_TAG_typedef"; + case DW_TAG_union_type: return "DW_TAG_union_type"; + case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters"; + case DW_TAG_variant: return "DW_TAG_variant"; + case DW_TAG_common_block: return "DW_TAG_common_block"; + case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion"; + case DW_TAG_inheritance: return "DW_TAG_inheritance"; + case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine"; + case DW_TAG_module: return "DW_TAG_module"; + case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type"; + case DW_TAG_set_type: return "DW_TAG_set_type"; + case DW_TAG_subrange_type: return "DW_TAG_subrange_type"; + case DW_TAG_with_stmt: return "DW_TAG_with_stmt"; + case DW_TAG_access_declaration: return "DW_TAG_access_declaration"; + case DW_TAG_base_type: return "DW_TAG_base_type"; + case DW_TAG_catch_block: return "DW_TAG_catch_block"; + case DW_TAG_const_type: return "DW_TAG_const_type"; + case DW_TAG_constant: return "DW_TAG_constant"; + case DW_TAG_enumerator: return "DW_TAG_enumerator"; + case DW_TAG_file_type: return "DW_TAG_file_type"; + case DW_TAG_friend: return "DW_TAG_friend"; + case DW_TAG_namelist: return "DW_TAG_namelist"; + case DW_TAG_namelist_item: return "DW_TAG_namelist_item"; + case DW_TAG_packed_type: return "DW_TAG_packed_type"; + case DW_TAG_subprogram: return "DW_TAG_subprogram"; + case DW_TAG_template_type_parameter: return "DW_TAG_template_type_parameter"; + case DW_TAG_template_value_parameter: return "DW_TAG_template_value_parameter"; + case DW_TAG_thrown_type: return "DW_TAG_thrown_type"; + case DW_TAG_try_block: return "DW_TAG_try_block"; + case DW_TAG_variant_part: return "DW_TAG_variant_part"; + case DW_TAG_variable: return "DW_TAG_variable"; + case DW_TAG_volatile_type: return "DW_TAG_volatile_type"; + case DW_TAG_dwarf_procedure: return "DW_TAG_dwarf_procedure"; + case DW_TAG_restrict_type: return "DW_TAG_restrict_type"; + case DW_TAG_interface_type: return "DW_TAG_interface_type"; + case DW_TAG_namespace: return "DW_TAG_namespace"; + case DW_TAG_imported_module: return "DW_TAG_imported_module"; + case DW_TAG_unspecified_type: return "DW_TAG_unspecified_type"; + case DW_TAG_partial_unit: return "DW_TAG_partial_unit"; + case DW_TAG_imported_unit: return "DW_TAG_imported_unit"; + case DW_TAG_mutable_type: return "DW_TAG_mutable_type"; + case DW_TAG_condition: return "DW_TAG_condition"; + case DW_TAG_shared_type: return "DW_TAG_shared_type"; + default: return "Unrecognised TAG"; + } +} + +char * GetDwarfAttr(Dwarf_Half attr){ + switch (attr){ + case DW_AT_sibling: return "DW_AT_sibling"; + case DW_AT_location: return "DW_AT_location"; + case DW_AT_name: return "DW_AT_name"; + case DW_AT_ordering: return "DW_AT_ordering"; + case DW_AT_subscr_data: return "DW_AT_subscr_data"; + case DW_AT_byte_size: return "DW_AT_byte_size"; + case DW_AT_bit_offset: return "DW_AT_bit_offset"; + case DW_AT_bit_size: return "DW_AT_bit_size"; + case DW_AT_element_list: return "DW_AT_element_list"; + case DW_AT_stmt_list: return "DW_AT_stmt_list"; + case DW_AT_low_pc: return "DW_AT_low_pc"; + case DW_AT_high_pc: return "DW_AT_high_pc"; + case DW_AT_language: return "DW_AT_language"; + case DW_AT_member: return "DW_AT_member"; + case DW_AT_discr: return "DW_AT_discr"; + case DW_AT_discr_value: return "DW_AT_discr_value"; + case DW_AT_visibility: return "DW_AT_visibility"; + case DW_AT_import: return "DW_AT_import"; + case DW_AT_string_length: return "DW_AT_string_length"; + case DW_AT_common_reference: return "DW_AT_common_reference"; + case DW_AT_comp_dir: return "DW_AT_comp_dir"; + case DW_AT_const_value: return "DW_AT_const_value"; + case DW_AT_containing_type: return "DW_AT_containing_type"; + case DW_AT_default_value: return "DW_AT_default_value"; + case DW_AT_inline: return "DW_AT_inline"; + case DW_AT_is_optional: return "DW_AT_is_optional"; + case DW_AT_lower_bound: return "DW_AT_lower_bound"; + case DW_AT_producer: return "DW_AT_producer"; + case DW_AT_prototyped: return "DW_AT_prototyped"; + case DW_AT_return_addr: return "DW_AT_return_addr"; + case DW_AT_start_scope: return "DW_AT_start_scope"; + case DW_AT_bit_stride: return "DW_AT_bit_stride"; + case DW_AT_upper_bound: return "DW_AT_upper_bound"; + case DW_AT_abstract_origin: return "DW_AT_abstract_origin"; + case DW_AT_accessibility: return "DW_AT_accessibility"; + case DW_AT_address_class: return "DW_AT_address_class"; + case DW_AT_artificial: return "DW_AT_artificial"; + case DW_AT_base_types: return "DW_AT_base_types"; + case DW_AT_calling_convention: return "DW_AT_calling_convention"; + case DW_AT_count: return "DW_AT_count"; + case DW_AT_data_member_location: return "DW_AT_data_member_location"; + case DW_AT_decl_column: return "DW_AT_decl_column"; + case DW_AT_decl_file: return "DW_AT_decl_file"; + case DW_AT_decl_line: return "DW_AT_decl_line"; + case DW_AT_declaration: return "DW_AT_declaration"; + case DW_AT_discr_list: return "DW_AT_discr_list"; + case DW_AT_encoding: return "DW_AT_encoding"; + case DW_AT_external: return "DW_AT_external"; + case DW_AT_frame_base: return "DW_AT_frame_base"; + case DW_AT_friend: return "DW_AT_friend"; + case DW_AT_identifier_case: return "DW_AT_identifier_case"; + case DW_AT_macro_info: return "DW_AT_macro_info"; + case DW_AT_namelist_item: return "DW_AT_namelist_item"; + case DW_AT_priority: return "DW_AT_priority"; + case DW_AT_segment: return "DW_AT_segment"; + case DW_AT_specification: return "DW_AT_specification"; + case DW_AT_static_link: return "DW_AT_static_link"; + case DW_AT_type: return "DW_AT_type"; + case DW_AT_use_location: return "DW_AT_use_location"; + case DW_AT_variable_parameter: return "DW_AT_variable_parameter"; + case DW_AT_virtuality: return "DW_AT_virtuality"; + case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location"; + case DW_AT_allocated: return "DW_AT_allocated"; + case DW_AT_associated: return "DW_AT_associated"; + case DW_AT_data_location: return "DW_AT_data_location"; + case DW_AT_byte_stride: return "DW_AT_byte_stride"; + case DW_AT_entry_pc: return "DW_AT_entry_pc"; + case DW_AT_use_UTF8: return "DW_AT_use_UTF8"; + case DW_AT_extension: return "DW_AT_extension"; + case DW_AT_ranges: return "DW_AT_ranges"; + case DW_AT_trampoline: return "DW_AT_trampoline"; + case DW_AT_call_column: return "DW_AT_call_column"; + case DW_AT_call_file: return "DW_AT_call_file"; + case DW_AT_call_line: return "DW_AT_call_line"; + case DW_AT_description: return "DW_AT_description"; + case DW_AT_binary_scale: return "DW_AT_binary_scale"; + case DW_AT_decimal_scale: return "DW_AT_decimal_scale"; + case DW_AT_small: return "DW_AT_small"; + case DW_AT_decimal_sign: return "DW_AT_decimal_sign"; + case DW_AT_digit_count: return "DW_AT_digit_count"; + case DW_AT_picture_string: return "DW_AT_picture_string"; + case DW_AT_mutable: return "DW_AT_mutable"; + case DW_AT_threads_scaled: return "DW_AT_threads_scaled"; + case DW_AT_explicit: return "DW_AT_explicit"; + case DW_AT_object_pointer: return "DW_AT_object_pointer"; + case DW_AT_endianity: return "DW_AT_endianity"; + case DW_AT_elemental: return "DW_AT_elemental"; + case DW_AT_pure: return "DW_AT_pure"; + case DW_AT_recursive: return "DW_AT_recursive"; + + default: return "Unrecognised ATTR"; + } + +} + +char * GetDwarfForm(Dwarf_Half form){ + switch (form){ + case DW_FORM_addr: return "DW_FORM_addr"; + case DW_FORM_block2: return "DW_FORM_block2"; + case DW_FORM_block4: return "DW_FORM_block4"; + case DW_FORM_data2: return "DW_FORM_data2"; + case DW_FORM_data4: return "DW_FORM_data4"; + case DW_FORM_data8: return "DW_FORM_data8"; + case DW_FORM_string: return "DW_FORM_string"; + case DW_FORM_block: return "DW_FORM_block"; + case DW_FORM_block1: return "DW_FORM_block1"; + case DW_FORM_data1: return "DW_FORM_data1"; + case DW_FORM_flag: return "DW_FORM_flag"; + case DW_FORM_sdata: return "DW_FORM_sdata"; + case DW_FORM_strp: return "DW_FORM_strp"; + case DW_FORM_udata: return "DW_FORM_udata"; + case DW_FORM_ref_addr: return "DW_FORM_ref_addr"; + case DW_FORM_ref1: return "DW_FORM_ref1"; + case DW_FORM_ref2: return "DW_FORM_ref2"; + case DW_FORM_ref4: return "DW_FORM_ref4"; + case DW_FORM_ref8: return "DW_FORM_ref8"; + case DW_FORM_ref_udata: return "DW_FORM_ref_udata"; + case DW_FORM_indirect: return "DW_FORM_indirect"; + default: return "Unrecognised FORM"; + } +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/e32romimage.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/e32romimage.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include +#include +#include + +#include "elfromerror.h" +#include "e32romimage.h" + + +void E32RomImage::SetupRomData(){ + // see if there's a header on the image. + iRomFile.GetData(&iE32RomHeader, sizeof(iE32RomHeader)); + + // In general the 'name' is of the form EPOC*ROM. + // We are looking for ARM roms for the moment so check for EPOCARM and error on anything + // else which matches EPOC*ROM + bool isEPOCHeader = !strncmp((const char *)&iE32RomHeader.name[0], "EPOC", 4) && + (strstr((const char *)&iE32RomHeader.name[0], "ROM") != NULL); + bool isARMHeader = !strncmp((const char *)&iE32RomHeader.name[0], "EPOCARM", 7); + + if(isARMHeader) + iRomFile.SetOffset(sizeof(iE32RomHeader)); + else if (isEPOCHeader) + errx(EX_NOINPUT, "unsupported rom type: %s\n", (const char *)&iE32RomHeader.name[0]); +} + +void E32RomImage::GetFileFragmentData(FileFragmentData & aFileFragmentData ){ + assert(iRomFile.Size() > 0); + if (!iData) + iData = iRomFile.GetData(); + SetFileFragmentData(aFileFragmentData, Size(), reinterpret_cast(iData)); +} + +void E32RomImage::DeleteFileFragmentData(){ + if (iData) { + char * d = iData; + iData = NULL; + delete [] d; + } +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/e32romimage.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/e32romimage.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef E32ROMIMAGE_H_ +#define E32ROMIMAGE_H_ + +#include + +#include "defs.h" +#include "filefragment.h" +#include "inputfile.h" + +class E32RomImage : public FileFragmentOwner { +public: + typedef struct // this is the structure of an EPOC rom header + { + char name[16]; + unsigned char versionStr[4]; + unsigned char buildNumStr[4]; + unsigned long romSize; + unsigned long wrapSize; + } E32RomHeader; +public: + + E32RomImage(PathName aPath): + iRomFile(aPath), iData(NULL) + {}; + + void SetupRomData(); + + // The FileFragmentOwner protocol + virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ); + virtual size_t Size() { + assert(iRomFile.Size() - iRomFile.GetOffset()); + return iRomFile.Size() - iRomFile.GetOffset(); + }; + virtual void DeleteFileFragmentData(); + +private: + + void Open(); + void Close(); + void SetSize(); + +private: + InputFile iRomFile; + char * iData; + E32RomHeader iE32RomHeader; + + +}; + +#endif /*E32ROMIMAGE_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfdefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfdefs.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef ELFDEFS_H_ +#define ELFDEFS_H_ + +#include + +#endif /*ELFDEFS_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfheader.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfheader.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include "elfheader.h" + +Elf32Header::Elf32Header(Elf32_Ehdr & aHdr){ + iHdr = aHdr; + iHdr.e_entry = 0x0; + iHdr.e_phoff = iHdr.e_shoff = iHdr.e_shoff = 0; + iHdr.e_phnum = iHdr.e_shnum = iHdr.e_shstrndx = 0; + iHdr.e_ehsize = sizeof(Elf32_Ehdr); + // Let's say this is an executable rather than a shared object. + iHdr.e_type = ET_EXEC; +} + +void Elf32Header::GetFileFragmentData(FileFragmentData & aFileFragmentData ){ + SetFileFragmentData(aFileFragmentData, Size(), reinterpret_cast(&iHdr)); +} + + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfheader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfheader.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef ELFHEADER_H_ +#define ELFHEADER_H_ + +#include "elfdefs.h" +#include "filefragment.h" +//#include "outputfile.h" + +class Elf32Header : public FileFragmentOwner { +public: + Elf32Header(){}; + Elf32Header(Elf32_Ehdr & aHeader); + + void SetEntryPoint(Elf32_Addr addr) { iHdr.e_entry = addr; } + void SetProgramHdrOffset(Elf32_Off aOff) { iHdr.e_phoff = aOff; }; + void SetSectionHdrOffset(Elf32_Off aOff) { iHdr.e_shoff = aOff; }; + void AddProgramHdr() { iHdr.e_phnum++; }; + void AddSectionHdr() { iHdr.e_shnum++; }; + void SetSectionStringNdx(Elf32_Half ndx) { iHdr.e_shstrndx = ndx; }; + + // FileFragmentOwner protocol + virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ); + virtual size_t Size() { return sizeof(iHdr); }; + virtual void DeleteFileFragmentData() {}; + +private: + Elf32_Ehdr iHdr; +}; + +#endif /*ELFHEADER_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfphdr.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfphdr.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include "elfphdr.h" + +ElfPHdr & ElfPHdr::operator=(const ElfPHdr & aPHdr){ + iOffset = aPHdr.iOffset; + iElf32Phdr = aPHdr.iElf32Phdr; + return *this; +} + +ElfPHdr::ElfPHdr(const ElfPHdr & aPHdr){ + *this = aPHdr; +} + +#if 0 +void ElfPHdr::InitRom(RomDetails * aRomDetails, size_t aOffset){ + iElf32Phdr.p_type = PT_LOAD; + iElf32Phdr.p_offset = aOffset; + iElf32Phdr.p_vaddr = aRomDetails->iRomBaseLinearAddr; + iElf32Phdr.p_paddr = aRomDetails->iRomPhysAddr; + iElf32Phdr.p_align = 4; + iElf32Phdr.p_flags = PF_X + PF_R; + iElf32Phdr.p_filesz = iElf32Phdr.p_memsz = iRomImage.Size(); +} +#endif + +void ElfPHdr::GetFileFragmentData(FileFragmentData & aFileFragmentData ){ + SetFileFragmentData(aFileFragmentData, Size(), reinterpret_cast(&iElf32Phdr)); +} + diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfphdr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfphdr.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef ELFPHDR_H_ +#define ELFPHDR_H_ +#include + +#include "romdetails.h" +#include "elfheader.h" +#include "e32romimage.h" +#include "filefragment.h" +#include "outputfile.h" + +class ElfPHdr : public FileFragmentOwner { +public: + ElfPHdr(){} + + ElfPHdr(const ElfPHdr & aPHdr); + + ElfPHdr & operator=(const ElfPHdr & aPHdr); + + Elf32_Word GetPhdrFilesz(){ return iElf32Phdr.p_filesz; } + Elf32_Word GetPhdrOffset(){ return iElf32Phdr.p_offset; } + Elf32_Addr GetPhdrPaddr(){ return iElf32Phdr.p_paddr; } + + void SetPhdrType(Elf32_Word x) { iElf32Phdr.p_type = x; } + void SetPhdrOffset(Elf32_Off x) { iElf32Phdr.p_offset = x; } + void SetPhdrVaddr(Elf32_Addr x) { iElf32Phdr.p_vaddr = x; } + void SetPhdrPaddr(Elf32_Addr x) { iElf32Phdr.p_paddr = x; } + void SetPhdrFilesz(Elf32_Word x) { iElf32Phdr.p_filesz = x; } + void SetPhdrMemsz(Elf32_Word x) { iElf32Phdr.p_memsz = x; } + void SetPhdrFlags(Elf32_Word x) { iElf32Phdr.p_flags = x; } + void SetPhdrAlign(Elf32_Word x) { iElf32Phdr.p_align = x; } + + void InitRom(RomDetails * aRomDetails, size_t aOffset); + + virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ); + virtual size_t Size() { return sizeof(Elf32_Phdr); }; + virtual void DeleteFileFragmentData() {}; + +private: + +#if 0 + typedef struct { + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; + } Elf32_Phdr; +#endif + Elf32_Phdr iElf32Phdr; +}; + +#endif /*ELFPHDR_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfrom.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfrom.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,567 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include + +using namespace std; + +#include "elfromerror.h" +#include "elfrom.h" +#include "inputfile.h" + +#define NO_GAPS + +void ElfRom::SetupE32RomData() { + SetupRomElf32_EHdr(); + SetupRomImage(); +} + +// TODO: don't use primary file - fill header in by hand. +void ElfRom::SetupRomElf32_EHdr() { + //create ELF header + + unsigned char c[EI_NIDENT] = {ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, ELFCLASS32, ELFDATA2LSB, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + Elf32_Ehdr elf32_ehdr; + + for (int i=0; i iRomPhysAddr; + elf32_ehdr.e_shoff = sizeof(Elf32_Ehdr); + +// ARM specific flags +// e_entry contains a program-loader entry point +#define EF_ARM_HASENTRY 0x02 +// Each subsection of the symbol table is sorted by symbol value +#define EF_ARM_SYMSARESORTED 0x04 +// Symbols in dynamic symbol tables that are defined in sections +// included in program segment n have st_shndx = n+ 1. +#define EF_ARM_DYNSYMSUSESEGIDX 0x8 +// Mapping symbols precede other local symbols in the symbol table +#define EF_ARM_MAPSYMSFIRST 0x10 +// This masks an 8-bit version number, the version of the ARM EABI to +// which this ELF file conforms. This EABI is version 2. A value of 0 +// denotes unknown conformance. (current version is 0x02000000) +#define EF_ARM_EABIMASK 0xFF000000 + +#define EF_ARM_EABI_VERSION 0x02000000 +#define EF_ARM_BPABI_VERSION 0x04000000 + + elf32_ehdr.e_flags = EF_ARM_BPABI_VERSION | EF_ARM_HASENTRY; + elf32_ehdr.e_ehsize = sizeof(Elf32_Ehdr); + elf32_ehdr.e_phentsize = sizeof(Elf32_Phdr); + elf32_ehdr.e_shentsize = sizeof(Elf32_Shdr); + elf32_ehdr.e_shnum = 0; + elf32_ehdr.e_shstrndx = 0; + elf32_ehdr.e_phnum = 02; + new (&iElf32Header) Elf32Header(elf32_ehdr); +#if 0 + iElf32Header.SetEntryPoint(iRomDetails->iRomPhysAddr); + elf_end(e); + close(fd); +#endif + iElf32Header.SetEntryPoint(iRomDetails->iRomPhysAddr); + iElf32Header.AddData(iOutputFile); + assert(iElf32Header.GetOffset() == 0); + if (iRomDetails->iTrace){ + cout << "\nElf header added.\n"; + } + +} + + +void ElfRom::SetupRomImage(){ + // ensure image size is known and we know how to get hold of it + iE32RomImage.SetupRomData(); + iE32RomImage.AddData(iOutputFile); + assert(iE32RomImage.GetOffset() == iElf32Header.Size()); + if (iRomDetails->iTrace){ + size_t offset = iE32RomImage.GetOffset(); + size_t size = iE32RomImage.Size(); + cout << "\nAdded ROM image " << iRomDetails->iRomFile << "\n"; + cout.fill('0'); + cout << hex << " offset 0x" << setw(8) + << offset << " size = 0x" << setw(8) << size << "\n" ; + } +} + +void ElfRom::SetupProgramHeaderTable(){ + size_t offsetx = AddBootStrapProgramHeader(); + RomDetails::XIPFileList::iterator aXIPFile = iRomDetails->iXIPFiles.begin(); + RomDetails::XIPFileList::iterator end = iRomDetails->iXIPFiles.end(); + unsigned int p = iRomDetails->iRomPhysAddr; + unsigned int v = iRomDetails->iRomBaseLinearAddr; + int addend = v > p ? -(v - p) : p - v; + + if (iRomDetails->iTrace){ + cout << "\nAdding program headers for e32images\n"; + } + + while (aXIPFile != end) { + offsetx = SetupProgramHeaders(*aXIPFile, offsetx, addend); + aXIPFile++; + } + AddFinalHeader(offsetx); + +#ifdef NO_GAPS + // check there are no gaps or overlaps in the phdrs + Elf32_Word bsz = iBootStrapPHdr.GetPhdrFilesz(); + Elf32_Word coffset = iBootStrapPHdr.GetPhdrOffset() + bsz; + Elf32_Addr phys_addr = iBootStrapPHdr.GetPhdrPaddr() + bsz; + ElfPHdrList::iterator aCheckHdr = iElfPHdrList.begin(); + ElfPHdrList::iterator endCheckHdr = iElfPHdrList.end(); + while(aCheckHdr != endCheckHdr) { + Elf32_Word o = aCheckHdr->GetPhdrOffset(); + if (coffset != o){ + cerr << "Error: Phdr table broken - offsets incorrect\n"; + assert(coffset == o); + } + Elf32_Addr addr = aCheckHdr->GetPhdrPaddr(); + if (phys_addr > addr){ + cerr << "Error: Phdr table broken - physical addresses incorrect\n"; + assert(phys_addr <= addr); + } + size_t sz = aCheckHdr->GetPhdrFilesz(); + coffset = o + sz; + phys_addr = addr + sz; + aCheckHdr++; + } +#endif + + ElfPHdrList::iterator aHdr = iElfPHdrList.begin(); + ElfPHdrList::iterator endHdr = iElfPHdrList.end(); + while (aHdr != endHdr) { + aHdr->AddData(iOutputFile); + aHdr++; + } +} + +size_t ElfRom::AddBootStrapProgramHeader(){ + iBootStrapPHdr.SetPhdrType(PT_LOAD); + iBootStrapPHdr.SetPhdrOffset(iE32RomImage.GetOffset()); + iBootStrapPHdr.SetPhdrVaddr(iRomDetails->iRomPhysAddr); + iBootStrapPHdr.SetPhdrPaddr(iRomDetails->iRomPhysAddr); + iBootStrapPHdr.SetPhdrAlign(4); + iBootStrapPHdr.SetPhdrFlags(PF_X + PF_R); + size_t bootstrapsize = iRomDetails->iXIPFiles[0].iLoadAddr - iRomDetails->iRomBaseLinearAddr; + iBootStrapPHdr.SetPhdrFilesz(bootstrapsize); + iBootStrapPHdr.SetPhdrMemsz(bootstrapsize); + + iBootStrapPHdr.AddData(iOutputFile); + assert((iElf32Header.Size() + iE32RomImage.Size()) == iBootStrapPHdr.GetOffset()); + iElf32Header.AddProgramHdr(); + iElf32Header.SetProgramHdrOffset(iBootStrapPHdr.GetOffset()); + if (iRomDetails->iTrace){ + size_t offset = iBootStrapPHdr.GetOffset(); + cout << "\nAdded PHdr for bootstrap\n"; + cout.fill('0'); + cout << hex << " offset 0x" << setw(8) << offset + << " size = 0x" << setw(8) << bootstrapsize << "\n"; + } + + return iE32RomImage.GetOffset() + bootstrapsize; +} + +static inline size_t InitE32HdrPHdr(ElfPHdr & hdr, size_t offset, Elf32_Word vaddr, Elf32_Word paddr, Elf32_Word size){ + hdr.SetPhdrType(PT_LOAD); + hdr.SetPhdrOffset(offset); + hdr.SetPhdrVaddr(vaddr); + hdr.SetPhdrPaddr(paddr); + hdr.SetPhdrAlign(0); + hdr.SetPhdrFlags(PF_R); + hdr.SetPhdrFilesz(size); + hdr.SetPhdrMemsz(size); + + return offset + size; + +} +static inline size_t InitROPHdr(ElfPHdr & hdr, size_t offset, Elf32_Word vaddr, Elf32_Word paddr, Elf32_Word size){ + hdr.SetPhdrType(PT_LOAD); + hdr.SetPhdrOffset(offset); + hdr.SetPhdrVaddr(vaddr); + hdr.SetPhdrPaddr(paddr); + hdr.SetPhdrAlign(4); + hdr.SetPhdrFlags(PF_X + PF_R); + hdr.SetPhdrFilesz(size); + hdr.SetPhdrMemsz(size); + + return offset + size; + +} + +static inline size_t InitRWPHdr(ElfPHdr & hdr, size_t offset, Elf32_Word vaddr, Elf32_Word paddr, Elf32_Word fsize, Elf32_Word msize){ + hdr.SetPhdrType(PT_LOAD); + hdr.SetPhdrOffset(offset); + hdr.SetPhdrVaddr(vaddr); + hdr.SetPhdrPaddr(paddr); + hdr.SetPhdrAlign(4); + hdr.SetPhdrFlags(PF_X + PF_R); + hdr.SetPhdrFilesz(fsize); + hdr.SetPhdrMemsz(msize); + + return offset + fsize; + +} + +size_t ElfRom::SetupProgramHeaders(XIPFileDetails & aXIPFileDetails, size_t offset, int addend){ + ElfPHdr e32hdr; + Elf32_Word e32hdrVaddr = aXIPFileDetails.iLoadAddr; + Elf32_Word e32hdrPaddr = aXIPFileDetails.iLoadAddr + addend; + Elf32_Word e32hdrSize = aXIPFileDetails.iROAddr - aXIPFileDetails.iLoadAddr ; + size_t e32hdrOffsetInRom = aXIPFileDetails.iLoadAddr - iRomDetails->iRomBaseLinearAddr; + size_t e32hdrOffsetInElf = iE32RomImage.GetOffset() + e32hdrOffsetInRom; +#ifdef NO_GAPS + // But actually the offset we'll use is the one we were given as an argument. + // This means we need to adjust the size, vaddr and paddr by the difference + size_t diff = e32hdrOffsetInElf - offset; + e32hdrSize += diff; + e32hdrVaddr -= diff; + e32hdrPaddr -= diff; + offset = InitE32HdrPHdr(e32hdr, offset, e32hdrVaddr, e32hdrPaddr, e32hdrSize); +#else + offset = InitE32HdrPHdr(e32hdr, e32hdrOffsetInElf, e32hdrVaddr, e32hdrPaddr, e32hdrSize); +#endif + iElf32Header.AddProgramHdr(); + iElfPHdrList.push_back(e32hdr); + ElfPHdr thdr; + Elf32_Word textVaddr = aXIPFileDetails.iROAddr; + Elf32_Word textPaddr = aXIPFileDetails.iROAddr + addend; + Elf32_Word textSize = aXIPFileDetails.iROSize; + size_t textOffsetInRom = aXIPFileDetails.iROAddr - iRomDetails->iRomBaseLinearAddr; + size_t textOffsetInElf = iE32RomImage.GetOffset() + textOffsetInRom; + offset = InitROPHdr(thdr, textOffsetInElf, textVaddr, textPaddr, textSize); + iElf32Header.AddProgramHdr(); + iElfPHdrList.push_back(thdr); + + if (iRomDetails->iTrace){ + cout << " " << aXIPFileDetails.iE32File << "\n"; + cout.fill(' '); + cout << left << " .text\n"; + cout.fill('0'); + cout << " paddr = 0x" << right << setw(8) << textPaddr << " vaddr = 0x" << right << setw(8)<< textVaddr + << " offset = 0x" << right << setw(8) << textOffsetInElf + << " size = 0x" << setw(8) << textSize << "\n" << flush; + } + + if (aXIPFileDetails.iRWSize > 0){ + ElfPHdr dhdr; + Elf32_Word dataVaddr = aXIPFileDetails.iRWAddr; + Elf32_Word dataPaddr = aXIPFileDetails.iROMDataAddr + addend; + Elf32_Word fsize = aXIPFileDetails.iRWSize; + Elf32_Word msize = aXIPFileDetails.iBSSDataSize; + size_t dataOffsetInRom = aXIPFileDetails.iROMDataAddr - iRomDetails->iRomBaseLinearAddr; + size_t dataOffsetInElf = iE32RomImage.GetOffset() + dataOffsetInRom; + offset = InitRWPHdr(dhdr, dataOffsetInElf, dataVaddr, dataPaddr, fsize, msize); + iElf32Header.AddProgramHdr(); + iElfPHdrList.push_back(dhdr); + + if (iRomDetails->iTrace){ + cout.fill(' '); + cout << left << " .data\n"; + cout.fill('0'); + cout << " paddr = 0x" << right << setw(8) << dataPaddr << " vaddr = 0x" << right << setw(8)<< dataVaddr + << " offset = 0x" << right << setw(8)<< dataOffsetInElf + << " size = 0x" << right << setw(8) << fsize << "\n" << flush; + } + + } + return offset; +} + +// This adds a header for the remainder of the ROM image after the last XIP file +size_t ElfRom::AddFinalHeader(size_t offset){ + ElfPHdr & lastHdr = iElfPHdrList.back(); + Elf32_Word startAddr = lastHdr.GetPhdrPaddr() + lastHdr.GetPhdrFilesz(); + ElfPHdr e32hdr; + Elf32_Word e32hdrVaddr = startAddr; + Elf32_Word e32hdrPaddr = startAddr; + Elf32_Word e32hdrSize = iE32RomImage.Size() - offset + iE32RomImage.GetOffset(); + + offset = InitE32HdrPHdr(e32hdr, offset, e32hdrVaddr, e32hdrPaddr, e32hdrSize); + + iElf32Header.AddProgramHdr(); + iElfPHdrList.push_back(e32hdr); + + if (iRomDetails->iTrace){ + cout << "\nAdded final PHdr\n" << " offset 0x" << hex << right << setw(8) << offset + << " size = 0x" << setw(8) << e32hdrSize << "\n"; + } + return offset; +} + +void ElfRom::SetupAuxilarySections(){ + SetupLogFile(); +} + +void ElfRom::SetupLogFile(){ + if (!iRomDetails->iLogFile.size()) return; + InputFile * aLogFile = new InputFile(iRomDetails->iLogFile); + ElfSectionFileData * aLogFileData = new ElfSectionFileData(aLogFile); + Elf32_Shdr shdr; + shdr.sh_name = 0; // for now. + shdr.sh_offset = 0; // for now + shdr.sh_info = 0; + shdr.sh_link = SHN_UNDEF; + shdr.sh_addr = 0; + shdr.sh_addralign = 0; + shdr.sh_type = SHT_PROGBITS; + shdr.sh_size = 0; // for now. + shdr.sh_flags = 0; + shdr.sh_entsize = 0; + + ElfSection aLogFileSection(aLogFileData, "ROMLogFile", shdr); + iElfSectionManager.AddSection(aLogFileSection); + +} + +void ElfRom::SetupELFRomData() { + SetupProgramHeaderTable(); + SetupAuxilarySections(); + if (!iRomDetails->iStrip){ + SetupSectionHeaderTable(); + SetupSymbolTable(); + if (!iRomDetails->iNoDwarf){ + SetupDwarfSections(); + } + } +} + +void ElfRom::SetupSectionHeaderTable(){ + RomDetails::XIPFileList::iterator aXIPFile = iRomDetails->iXIPFiles.begin(); + RomDetails::XIPFileList::iterator end = iRomDetails->iXIPFiles.end(); + + if (iRomDetails->iTrace && aXIPFile != end){ + cout << "\nAdding Section headers from associated ELF files\n"; + } + + while (aXIPFile != end) { + SetupSectionHeaders(*aXIPFile); + aXIPFile++; + } +} + +void ElfRom::SetupSectionHeaders(XIPFileDetails & aXIPFileDetails) { + // Open ELF file + PathName aPath = aXIPFileDetails.iElfFile; + + if (aPath.size() == 0) return; + + int fd; + Elf * e; + size_t shstrndx; + bool hasSectionStringTable = true; + + + if ((fd = open(aPath.c_str(), O_RDONLY|O_BINARY, 0)) < 0){ + warnx(EX_NOINPUT, "open \"%s\" failed\n", aPath.c_str()); + goto finish; + } + if ((e = elf_begin(fd, ELF_C_READ , NULL)) == NULL) + errx(EX_SOFTWARE, "elf_begin() failed: %s.\n", elf_errmsg(-1)); + if (elf_kind(e) != ELF_K_ELF) + errx(EX_SOFTWARE, "file not of kind ELF_K_ELF: %s.\n", aPath.c_str()); + if (elf_getshstrndx(e, &shstrndx) == 0) { + hasSectionStringTable = false; + warnx(EX_SOFTWARE, "getshstrndx() failed for \"%s\"\n", aPath.c_str()); + } + if (hasSectionStringTable){ + SetUpSegmentInfo(aXIPFileDetails, e); + SetupSectionHeaders(aXIPFileDetails, e, shstrndx); + } + + elf_end(e); + close(fd); +finish: + return; +} + +void ElfRom::SetupSectionHeaders(XIPFileDetails & aXIPFileDetails, Elf * e, size_t shstrndx){ + // Iterate through sections looking for the ones we're after. Namely: + // text, data, bss/zi, symtab, strtable, and .debug* + Elf_Scn * scn = NULL; + Elf32_Shdr * shdr; + SectionNumberMap aSectionNumberMap; + SectionVaddrAddendMap aSectionVaddrAddendMap; + + String aPath(aXIPFileDetails.iElfFile); + + const char * debugName = ".debug"; + const size_t debugNameLength = strlen(debugName); + const char * staticStrTab = ".strtab"; + + if (iRomDetails->iTrace){ + cout << " " << aXIPFileDetails.iElfFile << "\n"; + } + + while ((scn = elf_nextscn(e, scn)) != NULL) { + + if ((shdr = elf32_getshdr(scn)) == NULL) + errx(EX_SOFTWARE, "getshdr() failed: %s.\n", elf_errmsg(-1)); + + size_t aOldNdx = elf_ndxscn(scn); + char * name = elf_strptr(e, shstrndx, shdr->sh_name); + VirtualAddr sectionAddr = shdr->sh_addr; + + switch (shdr->sh_type) { + case SHT_NOBITS: + // Check for BSS or ZI + if ((shdr->sh_flags & SHF_WRITE) && (shdr->sh_flags & SHF_ALLOC)) { + // set up section number mapping + size_t aNew = AddBssSectionHeader(aXIPFileDetails, shdr, name); + aSectionNumberMap.push_back(SectionNumberMapping(aOldNdx, aNew)); + // set up address adjustment for relocation of e.g. symbols + int addend = aXIPFileDetails.iBSSAddr - sectionAddr; + aSectionVaddrAddendMap.push_back(SectionVaddrAddendMapping(aOldNdx, addend)); + } + break; +#define ARM_EXIDX (SHT_LOPROC + 1) + case ARM_EXIDX: + case SHT_PROGBITS: + // text/ro or data/rw will have SHF_ALLOC set + if (shdr->sh_flags & SHF_ALLOC) { + size_t aNew = 0; + int addend = 0; + if (shdr->sh_flags & SHF_WRITE) { + aNew = AddRwSectionHeader(aXIPFileDetails, shdr, name); + addend = aXIPFileDetails.iRWAddr - sectionAddr; + } else { + aNew = AddRoSectionHeader(aXIPFileDetails, shdr, name); + addend = aXIPFileDetails.iROAddr - sectionAddr; + } + // set up section number mapping + aSectionNumberMap.push_back(SectionNumberMapping(aOldNdx, aNew)); + // set up address adjustment for relocation of e.g. symbols + aSectionVaddrAddendMap.push_back(SectionVaddrAddendMapping(aOldNdx, addend)); + } else if (!iRomDetails->iNoDwarf && !strncmp(debugName, name, debugNameLength)) { + iDwarfFound = true; + iDwarfManager.AddSection(aXIPFileDetails, name, shdr); + } + break; + case SHT_SYMTAB: + iElfSymbolTableManager.AddSymbolTable(aPath, shdr->sh_offset, shdr->sh_size, shdr->sh_info); + break; + case SHT_STRTAB: + if (!strcmp(staticStrTab, name)) + iElfSymbolTableManager.AddStringTable(aPath, shdr->sh_offset, shdr->sh_size); + break; + } + } + iElfSymbolTableManager.Finalize(aSectionNumberMap, aSectionVaddrAddendMap); +} + +size_t ElfRom::AddRoSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName){ + size_t delta = aShdr->sh_addr - aXIPFileDetails.iElfTextBase; + VirtualAddr vaddr = aXIPFileDetails.iROAddr + delta; + size_t offsetInRom = vaddr - iRomDetails->iRomBaseLinearAddr; + size_t offsetInElf = iE32RomImage.GetOffset() + offsetInRom; + aShdr->sh_addr = vaddr; + return AddROMSectionHeader(aXIPFileDetails, aShdr, aName, offsetInElf ); +} + +size_t ElfRom::AddRwSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName){ + size_t delta = aShdr->sh_addr - aXIPFileDetails.iElfDataBase; + VirtualAddr vaddr = aXIPFileDetails.iROMDataAddr + delta; + size_t offsetInRom = vaddr - iRomDetails->iRomBaseLinearAddr; + size_t offsetInElf = iE32RomImage.GetOffset() + offsetInRom; + aShdr->sh_addr = aXIPFileDetails.iRWAddr; + return AddROMSectionHeader(aXIPFileDetails, aShdr, aName, offsetInElf); +} + +size_t ElfRom::AddBssSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName){ + size_t delta = aShdr->sh_addr - aXIPFileDetails.iElfDataBase; + VirtualAddr vaddr = aXIPFileDetails.iROMDataAddr + delta; + size_t offsetInRom = vaddr - iRomDetails->iRomBaseLinearAddr; + size_t offsetInElf = iE32RomImage.GetOffset() + offsetInRom; + aShdr->sh_addr = aXIPFileDetails.iBSSAddr; + return AddROMSectionHeader(aXIPFileDetails, aShdr, aName, offsetInElf); +} + +size_t ElfRom::AddROMSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName, size_t aOffset){ + ElfSectionData * romData = aOffset ? + (ElfSectionData *)new ElfSectionRomData(aOffset, aShdr->sh_size) + : (ElfSectionData *)new ElfSectionNoData(); + ElfSection aSection(romData, aName, *aShdr); + iElfSectionManager.AddSection(aSection); + + if (iRomDetails->iTrace){ + cout.fill(' '); + cout << " " << left << setw(22) << aName << "\n"; + cout.fill('0'); + cout << " vaddr = 0x" << right << hex << setw(8) << aShdr->sh_addr << " offset = 0x" + << right << hex << setw(8) << aOffset + << " size = 0x" << right << hex << setw(8) << aShdr->sh_size << "\n"; + } + return aSection.GetIndex(); +} + +void ElfRom::SetUpSegmentInfo(XIPFileDetails & aXIPFileDetails, Elf * e){ + Elf32_Ehdr * ehdr = elf32_getehdr(e); + if (ehdr == NULL) + errx(EX_SOFTWARE, "elf32_getehdr() failed: %s.", elf_errmsg(-1)); + size_t n = ehdr->e_phnum; + Elf32_Phdr * phdr = elf32_getphdr(e); + if (phdr == NULL) + errx(EX_SOFTWARE, "elf32_getphdr() failed: %s.", elf_errmsg(-1)); + + for (size_t i = 0; i < n; i++) { + if (phdr[i].p_flags & PF_X){ + VirtualAddr segmentAddr = phdr[i].p_vaddr; + aXIPFileDetails.iElfTextBase = segmentAddr; + aXIPFileDetails.iElfTextLimit = segmentAddr + phdr[i].p_memsz; + + } else if (phdr[i].p_flags & PF_W){ + aXIPFileDetails.iElfDataBase = phdr[i].p_vaddr; + } + } +} + +void ElfRom::SetupSymbolTable(){ + iElfSymbolTableManager.AddSymbolTable(); + if (iRomDetails->iTrace){ + cout << "\nAdded section headers for combined symbol table and symbol string table\n"; + } +} + +void ElfRom::SetupDwarfSections(){ + if (iRomDetails->iTrace && iDwarfFound){ + cout << "\nSetting up Dwarf Sections\n"; + } else if (iRomDetails->iTrace && !iDwarfFound && !iRomDetails->iNoDwarf){ + cout << "\nWarning: No Dwarf information found\n"; + return; + } + iDwarfManager.SetupSections(); +} + +void ElfRom::AddData() { + iElfSectionManager.AddData(); + iElf32Header.SetSectionHdrOffset(iElfSectionManager.GetOffset()); +} + +void ElfRom::Dump(){ + iOutputFile.Dump(); + if (iRomDetails->iTrace){ + cout << "\nWrote " << iRomDetails->iElfRomFile << " " << dec << iOutputFile.Size() << " bytes\n"; + } +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfrom.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfrom.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,95 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef ELFROM_H_ +#define ELFROM_H_ + +#include +// +// Copyright (c) 2008 Symbian Software Ltd. All rights reserved. +// + +#include + +#include "romdetails.h" +#include "outputfile.h" +#include "elfheader.h" +#include "e32romimage.h" +#include "elfphdr.h" +#include "elfsectionmanager.h" +#include "elfsymboltablemanager.h" +#include "dwarfmanager.h" + +class ElfRom { +public: + ElfRom(RomDetails * aRomDetails) : + iRomDetails(aRomDetails), iOutputFile(aRomDetails->iElfRomFile), + iE32RomImage(aRomDetails->iRomFile), + iElfSectionManager(iElf32Header, iE32RomImage, iOutputFile), + iElfSymbolTableManager(iElf32Header, iE32RomImage, iOutputFile, iElfSectionManager), + iDwarfManager(iElfSectionManager, aRomDetails, iOutputFile), + iDwarfFound(false) + {} + void SetupE32RomData(); + void SetupELFRomData(); + void AddData(); + void Dump(); + +private: + typedef std::vector< Elf32_Shdr * > Elf32_Shdr_List; + +private: + void SetupRomElf32_EHdr(); + void SetupRomImage(); + void SetupProgramHeaderTable(); + size_t AddBootStrapProgramHeader(); + size_t SetupProgramHeaders(XIPFileDetails & aXIPFileDetails, size_t offset, int addend); + void SetupAuxilarySections(); + void SetupLogFile(); + void SetupSectionHeaderTable(); + void SetupSectionHeaders(XIPFileDetails & aXIPFileDetails); + void SetupSectionHeaders(XIPFileDetails & aXIPFileDetails, Elf * e, size_t shstrndx); + void SetUpSegmentInfo(XIPFileDetails & aXIPFileDetails, Elf * e); + size_t AddRoSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName); + size_t AddRwSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName); + size_t AddBssSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName); + size_t AddROMSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName, size_t aOffset); + size_t AddFinalHeader(size_t offset); + void SetupSymbolTable(); + void SetupDwarfSections(); + +private: + RomDetails * iRomDetails; + OutputFile iOutputFile; + + Elf32Header iElf32Header; + E32RomImage iE32RomImage; + + ElfPHdr iBootStrapPHdr; + + typedef std::vector ElfPHdrList; + ElfPHdrList iElfPHdrList; + + ElfSectionManager iElfSectionManager; + ElfSymbolTableManager iElfSymbolTableManager; + DwarfManager iDwarfManager; + + bool iDwarfFound; + +}; +#endif /*ELFROM_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfromerror.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfromerror.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include + +void errx(int errortype, const char * format, const char * msg) { + (void)errortype; + printf("ERROR: "); + printf(format, msg); + exit(EXIT_FAILURE); +} + +void warnx(int errortype, const char * format, const char * msg) { + (void)errortype; + printf("WARNING: "); + printf(format, msg); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfromerror.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfromerror.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef ELFROMERROR_H_ +#define ELFROMERROR_H_ + +#define EX_SOFTWARE 1 +#define EX_NOINPUT 2 +void errx(int errortype, const char * format, const char * msg); +void warnx(int errortype, const char * format, const char * msg); + +#endif /*ELFROMERROR_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfsection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfsection.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,123 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include "outputfile.h" +#include "inputfile.h" +#include "filefragment.h" +#include "elfsection.h" + + +ElfSection & ElfSection::operator=(const ElfSection & aSection) { + iSectionName = aSection.iSectionName; + iSectionHdr = aSection.iSectionHdr; + iSectionData = aSection.iSectionData->Clone(); + iIndex = aSection.iIndex; + return *this; +} + +ElfSection::ElfSection(const ElfSection & aSection){ + *this = aSection; +} + +ElfSectionRomData::ElfSectionRomData(const ElfSectionRomData & aData) { + iOffset = aData.iOffset; + iSize = aData.iSize; +} + +ElfSectionRomData * ElfSectionRomData::Clone(){ + return new ElfSectionRomData(*this); +} + +ElfSectionElfData::ElfSectionElfData(const ElfSectionElfData & aData) : + iSource(aData.iSource) +{ + iOffset = aData.iOffset; +} + +ElfSectionElfData * ElfSectionElfData::Clone(){ + return new ElfSectionElfData(*this); +} + +void ElfSectionElfData::AddData(OutputFile & aOutputFile){ + iSource.AddData(aOutputFile); +} + +void ElfSectionElfData::GetFileFragmentData(FileFragmentData & aFileFragmentData ){ + iSource.GetFileFragmentData(aFileFragmentData); +} + +void ElfSectionElfData::DeleteFileFragmentData(){ + iSource.DeleteFileFragmentData(); +} + +size_t ElfSectionElfData::Size(){ + return iSource.Size(); +} + +size_t ElfSectionElfData::GetOffset(){ + return iSource.GetOffset(); +} + +ElfSectionFileData::ElfSectionFileData(const ElfSectionFileData & aData) { + iOffset = aData.iOffset; + iInputFile = aData.iInputFile; + iData = aData.iData; +} + +ElfSectionFileData * ElfSectionFileData::Clone(){ + return new ElfSectionFileData(*this); +} + +void ElfSectionFileData::GetFileFragmentData(FileFragmentData & aFileFragmentData ){ + iData = iInputFile->GetData(); + SetFileFragmentData(aFileFragmentData, iInputFile->Size(), (char *)iData); +} + +void ElfSectionFileData::DeleteFileFragmentData(){ + if (iData) { + char * d = iData; + iData = NULL; + delete [] d; + } +} + +size_t ElfSectionFileData::Size(){ + return iInputFile->Size(); +} + +ElfSectionNoData::ElfSectionNoData(const ElfSectionNoData & aData) { + iOffset = aData.iOffset; +} + +ElfSectionNoData * ElfSectionNoData::Clone(){ + return new ElfSectionNoData(*this); +} + +void ElfSectionNoData::GetFileFragmentData(FileFragmentData & aFileFragmentData ){ + SetFileFragmentData(aFileFragmentData, 0u, reinterpret_cast(NULL)); +} + +ElfSection::~ElfSection(){ + delete iSectionData; +} + +void ElfSection::AddData(OutputFile & aOutputFile){ + iSectionData->AddData(aOutputFile); + SetSize(iSectionData->Size()); + SetOffset(iSectionData->GetOffset()); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfsection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfsection.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,182 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef ELFSECTION_H_ +#define ELFSECTION_H_ + +#include + +#include "defs.h" // for String + +#include "filefragment.h" +#include "inputfile.h" + +class ElfSectionHeader { +public: + ElfSectionHeader() + {} + + ElfSectionHeader(Elf32_Shdr & aShdr) : + iElf32Shdr(aShdr) + {} + + Elf32_Shdr iElf32Shdr; +}; + +class ElfSectionData : public FileFragmentOwner { +public: + ElfSectionData() + {} + ElfSectionData(size_t aOffset): + FileFragmentOwner(aOffset) + {} + virtual ElfSectionData * Clone() = 0; + + // The FileFragmentOwner protocol + virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ) = 0; + virtual size_t Size() = 0; + virtual void DeleteFileFragmentData() = 0; + + +}; + +class ElfSectionRomData : public ElfSectionData { +public: + ElfSectionRomData(size_t aOffset, size_t aSize) : + ElfSectionData(aOffset), + iSize(aSize) + {} + + ElfSectionRomData(const ElfSectionRomData & aData); + + // ElfSection protocol + virtual ElfSectionRomData * Clone(); + + // The FileFragmentOwner protocol + virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ){} + virtual size_t Size(){ return iSize; } + // Nothing to delete + virtual void DeleteFileFragmentData(){}; + // Dont add data; + virtual void AddData(OutputFile & aOutputFile) {}; + +private: + size_t iSize; +}; + +class ElfSectionElfData : public ElfSectionData { +public: + ElfSectionElfData(FileFragmentOwner & aSource) : + iSource(aSource) + {} + + ElfSectionElfData(const ElfSectionElfData & aData); + + // ElfSection protocol + virtual ElfSectionElfData * Clone(); + + // The FileFragmentOwner protocol + virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ); + virtual size_t Size(); + virtual void DeleteFileFragmentData(); + virtual void AddData(OutputFile & aOutputFile); + virtual size_t GetOffset(); + +private: + FileFragmentOwner & iSource; +}; + +class ElfSectionFileData : public ElfSectionData { +public: + ElfSectionFileData(InputFile * aInputFile) : + iInputFile(aInputFile), iData(NULL) + {} + ElfSectionFileData(const ElfSectionFileData & aData); + + // ElfSection protocol + virtual ElfSectionFileData * Clone(); + + // The FileFragmentOwner protocol + virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ); + virtual size_t Size(); + virtual void DeleteFileFragmentData(); + +private: + InputFile * iInputFile; + char * iData; +}; + +class ElfSectionNoData : public ElfSectionData { +public: + ElfSectionNoData(){} + + ElfSectionNoData(const ElfSectionNoData & aData); + + // ElfSection protocol + virtual ElfSectionNoData * Clone(); + + // The FileFragmentOwner protocol + virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ); + virtual size_t Size() { return 0; } + // Nothing to delete + virtual void DeleteFileFragmentData(){}; + // Dont add data; + virtual void AddData(OutputFile & aOutputFile) {}; + + + +private: + InputFile * iInputFile; +}; + +class ElfSection { +public: + ElfSection(ElfSectionData * aData) : + iSectionName(""), iSectionData(aData), iIndex(0) + {} + + ElfSection(ElfSectionData * aData, String aName, Elf32_Shdr & aShdr) : + iSectionName(aName), iSectionHdr(aShdr), iSectionData(aData) + {} + + ElfSection(const ElfSection & aData); + + ElfSection & operator=(const ElfSection & aSection); + + virtual ~ElfSection(); + + String & GetName() { return iSectionName ; } + void SetNameOffset(size_t nameOffset) { iSectionHdr.iElf32Shdr.sh_name = nameOffset; } + + ElfSectionHeader & GetSectionHeader() { return iSectionHdr; } + + void SetSize(size_t aSize) { iSectionHdr.iElf32Shdr.sh_size = aSize; } + void SetOffset(size_t aOffset) { iSectionHdr.iElf32Shdr.sh_offset = aOffset; } + + virtual void AddData(OutputFile & aOutputFile); + unsigned int GetIndex() { return iIndex; }; + void SetIndex(unsigned int aIndex) { iIndex = aIndex; }; + +private: + String iSectionName; + ElfSectionHeader iSectionHdr; + ElfSectionData * iSectionData; + unsigned int iIndex; +}; + +#endif /*ELFSECTION_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfsectionmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfsectionmanager.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,155 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include + +#include "elfsectionmanager.h" + +void ElfSectionManager::GetFileFragmentData(FileFragmentData & aFileFragmentData ){ + int nSections = iSections.size(); + if (nSections > 0){ + iData = new Elf32_Shdr[nSections]; + Elf32_Shdr * p = iData; + SectionList::iterator aSection = iSections.begin(); + SectionList::iterator end = iSections.end(); + while (aSection != end) { + *p = aSection->GetSectionHeader().iElf32Shdr; + p++; + aSection++; + } + SetFileFragmentData(aFileFragmentData, Size(), reinterpret_cast(iData)); + } +} + +size_t ElfSectionManager::Size(){ + return SectionHeaderSize(); +} + +void ElfSectionManager::DeleteFileFragmentData(){ + if (iData) { + Elf32_Shdr * d = iData; + iData = NULL; + delete[] d; + } +} + +void ElfSectionManager::AddData(){ + AddData(iOutputFile); +} + +void ElfSectionManager::AddData(OutputFile & aOutputFile){ + if (iSections.size() > 0) { + SectionList::iterator aSection = iSections.begin(); + SectionList::iterator end = iSections.end(); + while (aSection != end) { + aSection->AddData(aOutputFile); + aSection++; + } + AddSectionTable(); + } +} + +void ElfSectionManager::EnsureSectionStringTableSectionAdded(){ + if (iSectionStringTableSectionAdded) return; + + // set iSectionStringTableSectionAdded true now so we don't do the next bit twice; + iSectionStringTableSectionAdded = true; + + // first create the UNDEF section + ElfSectionNoData * aUndefData = new ElfSectionNoData(); + + Elf32_Shdr undef; + undef.sh_name = 0; + undef.sh_type = SHT_NULL; + undef.sh_flags = 0; + undef.sh_addr = 0; + undef.sh_offset = 0; + undef.sh_size = 0; + undef.sh_link = 0; + undef.sh_info = 0; + undef.sh_addralign = 0; + undef.sh_entsize = 0; + + ElfSection aUndefSection(aUndefData, "", undef); + AddSection(aUndefSection); + + ElfSectionElfData * aSectionStringTableSectionData = new ElfSectionElfData(iStringTable); + Elf32_Shdr shdr; + shdr.sh_name = 0; // for now. + shdr.sh_type = SHT_STRTAB; + shdr.sh_flags = 0; + shdr.sh_addr = 0; + shdr.sh_offset = 0; // for now + shdr.sh_size = 0; // for now. + shdr.sh_link = SHN_UNDEF; + shdr.sh_info = 0; + shdr.sh_addralign = 0; + shdr.sh_entsize = 0; + + ElfSection aSectionStringTableSection(aSectionStringTableSectionData, ".shstrtab", shdr); + AddSection(aSectionStringTableSection); + iElf32Header.SetSectionStringNdx(iSections.size() - 1); +} +void ElfSectionManager::AddSection(ElfSection & aSection){ + EnsureSectionStringTableSectionAdded(); + if (aSection.GetName().size() > 0){ + // rename sections for GDB (yuk!) + String sectionName(aSection.GetName()); + String ro("ER_RO"); + String text(".text"); + if (sectionName == ro){ + sectionName = text; + } else { + String rw("ER_RW"); + String data(".data"); + if (sectionName == rw){ + sectionName = data; + } else { + String zi("ER_ZI"); + String bss(".bss"); + if (sectionName == zi) + sectionName = bss; + } + } + size_t nameOffset = iStringTable.AddName(sectionName); + aSection.SetNameOffset(nameOffset); + } else { + // use the initial Null String. + size_t nameOffset = iStringTable.AllocateInitialNullString(); + aSection.SetNameOffset(nameOffset); + } + aSection.SetIndex(iSections.size()); + iSections.push_back(aSection); + iElf32Header.AddSectionHdr(); +} + +size_t ElfSectionManager::SectionHeaderSize(){ + return iSections.size() * sizeof(Elf32_Shdr); +} + +void ElfSectionManager::AddSectionStringTable(){ + // Assume the section header already setup and we've got hold of it. We need to say where the strings ended up. + const FileFragment & aSectionTableFrag = iOutputFile.GetFileFragment(this); + SetOffset(aSectionTableFrag.GetOffset()); +} + +void ElfSectionManager::AddSectionTable(){ + const FileFragment & aSectionTableFrag = iOutputFile.GetFileFragment(this); + SetOffset(aSectionTableFrag.GetOffset()); + iElf32Header.SetSectionHdrOffset(GetOffset()); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfsectionmanager.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfsectionmanager.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,89 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef ELFSECTIONMANAGER_H_ +#define ELFSECTIONMANAGER_H_ + +#include + +#include "filefragment.h" +// +// Copyright (c) 2008 Symbian Software Ltd. All rights reserved. +// + +#include "elfstringtable.h" +#include "outputfile.h" +#include "elfheader.h" +#include "e32romimage.h" +#include "elfsection.h" +#include "defs.h" // String + + +class ElfSectionHeaderStringTable : public ElfStringTable { +public: + size_t AddName(String aName) { + return AddString(aName); + } + +}; + +class ElfSectionManager : public FileFragmentOwner { +public: + ElfSectionManager(Elf32Header & aElf32Header, E32RomImage & aRomImage, OutputFile & aOutputFile) : + iElf32Header(aElf32Header), iRomImage(aRomImage), + iOutputFile(aOutputFile), iOffset(0), iData(NULL), + iSectionStringTableSectionAdded(false) + {} + + // The FileFragmentOwner protocol + virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ); + virtual size_t Size(); + virtual void DeleteFileFragmentData(); + virtual void AddData(OutputFile & aOutputFile); + + void AddData(); + void AddSection(ElfSection & aSection); + + int NumSections() { return iSections.size(); } + +private: + // Don't want one of these to be copied + ElfSectionManager(const ElfSectionManager & aElfSectionManager); + + ElfSectionManager & operator=(const ElfSectionManager & aElfSectionManager); + +private: + size_t SectionHeaderSize(); + void AddSectionStringTable(); + void AddSectionTable(); + void EnsureSectionStringTableSectionAdded(); + +private: + typedef std::vector SectionList; + Elf32Header & iElf32Header; + E32RomImage & iRomImage; + OutputFile & iOutputFile; + SectionList iSections; + size_t iOffset; + ElfSectionHeaderStringTable iStringTable; + Elf32_Shdr * iData; + bool iSectionStringTableSectionAdded; + +}; + +#endif /*ELFSECTIONMANAGER_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfstringtable.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfstringtable.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include + +#include "elfstringtable.h" + +void ElfStringTable::GetFileFragmentData(FileFragmentData & aFileFragmentData ){ + size_t nbytes = Size(); + iData = new char[nbytes]; + memset(iData, 0, nbytes); + if (iStrings.size() > 0) { + StringList::iterator aString = iStrings.begin(); + StringList::iterator end = iStrings.end(); + while (aString != end) { + memcpy(iData + aString->iOffset, aString->iName.data(), aString->iName.size()); + aString++; + } + } + SetFileFragmentData(aFileFragmentData, nbytes, reinterpret_cast(iData)); +} + +size_t ElfStringTable::Size() { + return iSize; +} + +void ElfStringTable::DeleteFileFragmentData(){ + if (iData) { + char * d = iData; + iData = NULL; + delete [] d; + } +} + +size_t ElfStringTable::AddString(String aString){ + size_t offset = iSize; + StringTableEntry sn(aString, offset); + iStrings.push_back(sn); + size_t ss = aString.size(); + iSize += (ss + 1); + return offset; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfstringtable.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfstringtable.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef ELFSTRINGTABLE_H_ +#define ELFSTRINGTABLE_H_ + +// +// Copyright (c) 2008 Symbian Software Ltd. All rights reserved. +// + +#include + +#include "defs.h" +#include "filefragment.h" +#include "outputfile.h" + +class ElfStringTable : public FileFragmentOwner { +public: + ElfStringTable() : + iSize(0), iData(NULL) + {} + + ~ElfStringTable(){ + iStrings.clear(); + if (iData) { + char * d = iData; + iData = NULL; + delete d; + } + } + + // The FileFragmentOwner protocol + virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ); + virtual size_t Size(); + virtual void SetSize(size_t aSize) + { iSize = aSize; } + virtual void DeleteFileFragmentData(); + + size_t AddString(String aName); + size_t AllocateInitialNullString() { + if (iSize == 0) { + StringTableEntry sn("", 0); + iStrings.push_back(sn); + iSize = 1; + } + // The initial string is always at offset 0 in the section. + return 0; + } + +private: + class StringTableEntry { + public: + StringTableEntry(String aName, size_t aOffset): + iName(aName), iOffset(aOffset) + {} + + String iName; + size_t iOffset; + }; + + typedef std::vector StringList; + + StringList iStrings; + size_t iSize; + char * iData; +}; + +#endif /*ELFSTRINGTABLE_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfsymboltablemanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfsymboltablemanager.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,259 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include + +#include "elfsymboltablemanager.h" + +void ElfFileSymbolFragments::AddSymbolTable(String & aPath, size_t aOffset, size_t aSize, size_t aFirstGlobal){ + iPath = aPath; + // drop the inital 'undefined' symbol + iSymbolTableOffset = aOffset + sizeof(Elf32_Sym); + iSymbolTableSize = aSize - sizeof(Elf32_Sym); + iFirstGlobal = aFirstGlobal - 1; +} + +void ElfFileSymbolFragments::AddStringTable(String & aPath, size_t aOffset, size_t aSize){ + iPath = aPath; + // drop the inital "\0" + iStringTableOffset = aOffset + 1; + iStringTableSize = aSize - 1; +} + +size_t ElfFileSymbolFragments::LookupSection(size_t ndx){ + SectionNumberMap::iterator aMapping = iSectionNumberMap.begin(); + SectionNumberMap::iterator end = iSectionNumberMap.end(); + while (aMapping != end) { + if (aMapping->iOld == ndx) + return aMapping->iNew; + aMapping++; + } + return ndx; +} + +int ElfFileSymbolFragments::LookupVaddrAddend(size_t ndx){ + SectionVaddrAddendMap::iterator aMapping = iSectionVaddrAddendMap.begin(); + SectionVaddrAddendMap::iterator end = iSectionVaddrAddendMap.end(); + while (aMapping != end) { + if (aMapping->iSectionNumber == ndx) + return aMapping->iAddend; + aMapping++; + } + return 0; +} + +size_t ElfSymTabStringTable::Size(){ + return iElfSymbolTableManager.GetSymTabStringsSectionSize(); +} + +void ElfSymbolTableManager::Finalize(SectionNumberMap & aSectionNumberMap, SectionVaddrAddendMap & aSectionVaddrAddendMap ){ + iCurrentFragment.SetSectionNumberMap(aSectionNumberMap); + iCurrentFragment.SetSectionVaddrAddendMap(aSectionVaddrAddendMap); + iCurrentFragment.Validate(); + iSymbolFragments.push_back(iCurrentFragment); + iCurrentFragment.Reset(); +} + +// TODO: This could be done more efficiently and with out the use of the ElfStringTable object. +void ElfSymbolTableManager::GetFileFragmentData(FileFragmentData & aFileFragmentData ){ + size_t symTabSize = GetSymTabSectionSize(); + iData = new char[symTabSize]; + Elf32_Sym * syms = (Elf32_Sym *)iData; + + + // set up UNDEF symbol + syms[0].st_info = 0; + syms[0].st_name = 0; + syms[0].st_other = 0; + syms[0].st_shndx = 0; + syms[0].st_size = 0; + syms[0].st_value = 0; + + // set up 'cursors' into final symbol table so we put locals first + // and globals at the end + Elf32_Sym * lsym = &syms[1]; + size_t firstGlobal = GetFirstNonLocalIndex(); + Elf32_Sym * gsym = &syms[firstGlobal]; + Elf32_Sym * lsymLim = gsym; + iStringTable.AllocateInitialNullString(); + + SymbolFragmentList::iterator aFrag = iSymbolFragments.begin(); + SymbolFragmentList::iterator end = iSymbolFragments.end(); + while (aFrag != end) { + //InputFile aFile((char *)(aFrag->GetPath().c_str())); + InputFile aFile(aFrag->GetPath()); + aFile.SetOffset(aFrag->GetSymbolTableOffset()); + size_t symSize = aFrag->GetSymbolTableSize(); + size_t limit = symSize / sizeof(Elf32_Sym); + char * symtabData = aFile.GetData(symSize); + Elf32_Sym * symtab = (Elf32_Sym *)symtabData; + aFile.SetOffset(aFrag->GetStringTableOffset()); + char * strtabx = aFile.GetData(aFrag->GetStringTableSize()); + // set strtab back one to 'add' "\0" back in so indexs works with addition. + char * strtab = strtabx - 1; + size_t firstNonLocal = aFrag->GetFirstGlobal(); + + typedef std::map SymbolNdxMap; + SymbolNdxMap symNdxMap; + + for (size_t i = 0; i < limit; i++){ + size_t strndx = symtab[i].st_name; + + if (strndx != 0) { + // see if we've already seen this index + SymbolNdxMap::iterator res = symNdxMap.find(strndx); + size_t newndx; + if (res != symNdxMap.end()){ + newndx = res->second; + symtab[i].st_name = newndx; + } else { + char * name = &strtab[strndx]; + newndx = iStringTable.AddString(name); + symNdxMap[strndx] = symtab[i].st_name = newndx; + } + } + + if (!(symtab[i].st_value || symtab[i].st_size)){ + symtab[i].st_shndx = SHN_UNDEF; + } else { + size_t oldNdx = symtab[i].st_shndx; + + // retrieve new section index + size_t newscnndx = aFrag->LookupSection(oldNdx); + // retrieve the vaddr adjustment to add to the symbol's value + int addend = aFrag->LookupVaddrAddend(oldNdx); + symtab[i].st_shndx = newscnndx; + symtab[i].st_value += addend; + } + if (i < firstNonLocal){ + assert(lsym < lsymLim); + *(lsym++) = symtab[i]; + } else { + *(gsym++) = symtab[i]; + } + } + + delete [] symtabData; + delete strtabx; + + aFrag++; + } + SetFileFragmentData(aFileFragmentData, symTabSize, reinterpret_cast(iData)); +} + + +size_t ElfSymbolTableManager::Size(){ + return GetSymTabSectionSize(); +} + +void ElfSymbolTableManager::DeleteFileFragmentData(){ + char * d = iData; + iData = NULL; + delete [] d; +} + +void ElfSymbolTableManager::AddData(OutputFile & aOutputFile){ + const FileFragment & aSectionFrag = iOutputFile.GetFileFragment(this); + SetOffset(aSectionFrag.GetOffset()); +} + +void ElfSymbolTableManager::AddSymbolTable(){ + // The sym table section needs to record the index of its associated + // string table in its link field and record the index of the first non-local + // symbol in its info field + int symTabSize = GetSymTabSectionSize(); + size_t firstNonLocal = GetFirstNonLocalIndex(); + size_t nextSectionIndex = iElfSectionManager.NumSections(); + + ElfSectionElfData * aSymTabSectionData = new ElfSectionElfData(*this); + Elf32_Shdr symTabShdr; + symTabShdr.sh_name = 0; // for now. + symTabShdr.sh_type = SHT_SYMTAB; + symTabShdr.sh_flags = 0; + symTabShdr.sh_addr = 0; + symTabShdr.sh_offset = 0; // for now + symTabShdr.sh_size = symTabSize; // for now. + // symTabShdr will be @ index nextSectionIndex so the .strtab will + // be @ nextSectionIndex +1 + symTabShdr.sh_link = nextSectionIndex + 1; + symTabShdr.sh_info = firstNonLocal; + symTabShdr.sh_addralign = 4; + symTabShdr.sh_entsize = sizeof(Elf32_Sym); + + ElfSection aSymTabSection(aSymTabSectionData, ".symtab", symTabShdr); + iElfSectionManager.AddSection(aSymTabSection); + + + ElfSectionElfData * aStringTableSectionData = new ElfSectionElfData(iStringTable); + Elf32_Shdr shdr; + shdr.sh_name = 0; // for now. + shdr.sh_type = SHT_STRTAB; + shdr.sh_flags = 0; + shdr.sh_addr = 0; + shdr.sh_offset = 0; // for now + shdr.sh_size = GetSymTabStringsSectionSize(); + shdr.sh_link = 0; + shdr.sh_info = 0; + shdr.sh_addralign = 0; + shdr.sh_entsize = 0; + ElfSection aStringTableSection(aStringTableSectionData, ".strtab", shdr); + iElfSectionManager.AddSection(aStringTableSection); + +} + +size_t ElfSymbolTableManager::GetSymTabSectionSize(){ + int symTabSize = sizeof(Elf32_Sym); // add the 'undefined' symbols + + SymbolFragmentList::iterator aFrag = iSymbolFragments.begin(); + SymbolFragmentList::iterator end = iSymbolFragments.end(); + while (aFrag != end) { + symTabSize += aFrag->GetSymbolTableSize(); + aFrag++; + } + return symTabSize; +} + +size_t ElfSymbolTableManager::GetSymTabStringsSectionSize(){ + + if (iSymbolStringTableSizeValid) + return iSymbolStringTableSize; + + int stringsSize = 1; // add the leading "\0" + + SymbolFragmentList::iterator aFrag = iSymbolFragments.begin(); + SymbolFragmentList::iterator end = iSymbolFragments.end(); + while (aFrag != end) { + stringsSize += aFrag->GetStringTableSize(); + aFrag++; + } + iSymbolStringTableSizeValid = true; + return iSymbolStringTableSize = stringsSize; +} + +size_t ElfSymbolTableManager::GetFirstNonLocalIndex(){ + int ndx = 1; // add the 'undefined' symbols + + SymbolFragmentList::iterator aFrag = iSymbolFragments.begin(); + SymbolFragmentList::iterator end = iSymbolFragments.end(); + while (aFrag != end) { + ndx += aFrag->GetFirstGlobal(); + aFrag++; + } + return ndx; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/elfsymboltablemanager.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfsymboltablemanager.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,233 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef ELFSYMBOLTABLEMANAGER_H_ +#define ELFSYMBOLTABLEMANAGER_H_ + +#include +#include + +#include "filefragment.h" +#include "elfstringtable.h" +#include "outputfile.h" +#include "elfheader.h" +#include "e32romimage.h" +#include "elfsection.h" +#include "elfsectionmanager.h" +#include "defs.h" // String + +class ElfSymbolTableManager; + +class SectionNumberMapping { +public: + SectionNumberMapping(size_t aOld, size_t aNew): + iOld(aOld), iNew(aNew) + {} + + SectionNumberMapping & operator=(const SectionNumberMapping & aSectionNumberMapping){ + iOld = aSectionNumberMapping.iOld; + iNew = aSectionNumberMapping.iNew; + return *this; + } + + SectionNumberMapping(const SectionNumberMapping & aSectionNumberMapping){ + *this = aSectionNumberMapping; + } + + size_t iOld; + size_t iNew; +}; + +typedef std::vector< SectionNumberMapping > SectionNumberMap; + +class SectionVaddrAddendMapping { +public: + SectionVaddrAddendMapping(size_t aSectionNumber, signed int aAddend): + iSectionNumber(aSectionNumber), iAddend(aAddend) + {} + + SectionVaddrAddendMapping & operator=(const SectionVaddrAddendMapping & aSectionVaddrAddendMapping){ + iSectionNumber = aSectionVaddrAddendMapping.iSectionNumber; + iAddend = aSectionVaddrAddendMapping.iAddend; + return *this; + } + + SectionVaddrAddendMapping(const SectionVaddrAddendMapping & SectionVaddrAddendMapping){ + *this = SectionVaddrAddendMapping; + } + + size_t iSectionNumber; + signed int iAddend; +}; + +typedef std::vector< SectionVaddrAddendMapping > SectionVaddrAddendMap; + +class ElfFileSymbolFragments { +public: + ElfFileSymbolFragments(ElfSymbolTableManager * aElfSymbolTableManager): + iPath(""), + iSymbolTableOffset(0), iSymbolTableSize(0), + iFirstGlobal(0), + iStringTableOffset(0), iStringTableSize(0), + iElfSymbolTableManager(aElfSymbolTableManager) + { + iSectionNumberMap.clear(); + iSectionVaddrAddendMap.clear(); + } + + ElfFileSymbolFragments & operator=(const ElfFileSymbolFragments & aElfFileSymbolFragments){ + iPath = aElfFileSymbolFragments.iPath; + iSymbolTableOffset = aElfFileSymbolFragments.iSymbolTableOffset; + iSymbolTableSize = aElfFileSymbolFragments.iSymbolTableSize; + iFirstGlobal = aElfFileSymbolFragments.iFirstGlobal; + iStringTableOffset = aElfFileSymbolFragments.iStringTableOffset; + iStringTableSize = aElfFileSymbolFragments.iStringTableSize; + iSectionNumberMap = aElfFileSymbolFragments.iSectionNumberMap; + iSectionVaddrAddendMap = aElfFileSymbolFragments.iSectionVaddrAddendMap; + iElfSymbolTableManager = aElfFileSymbolFragments.iElfSymbolTableManager; + return *this; + } + + ElfFileSymbolFragments(const ElfFileSymbolFragments & aElfFileSymbolFragments){ + *this = aElfFileSymbolFragments; + } + + + + void AddSymbolTable(String & aPath, size_t aOffset, size_t aSize, size_t aFirstGlobal); + + void AddStringTable(String & aPath, size_t aOffset, size_t aSize); + String & GetPath() { return iPath; } + size_t GetSymbolTableOffset() { return iSymbolTableOffset; } + size_t GetSymbolTableSize() { return iSymbolTableSize; } + size_t GetFirstGlobal() { return iFirstGlobal; } + size_t GetStringTableOffset() { return iStringTableOffset; } + size_t GetStringTableSize() { return iStringTableSize; } + + void SetSectionNumberMap(SectionNumberMap & aSectionNumberMap){ + iSectionNumberMap = aSectionNumberMap; + } + + size_t LookupSection(size_t ndx); + + void SetSectionVaddrAddendMap(SectionVaddrAddendMap & aSectionVaddrAddendMap){ + iSectionVaddrAddendMap = aSectionVaddrAddendMap; + } + + int LookupVaddrAddend(size_t ndx); + + void Validate() { + assert(iPath.size() != 0); + assert(iSymbolTableOffset != 0); + assert(iSymbolTableSize != 0); + assert(iStringTableOffset != 0); + assert(iStringTableSize != 0); + assert(!iSectionNumberMap.empty()); + assert(!iSectionVaddrAddendMap.empty()); + } + + void Reset(){ + new (this) ElfFileSymbolFragments(iElfSymbolTableManager); + } + +private: + String iPath; + size_t iSymbolTableOffset; + size_t iSymbolTableSize; + size_t iFirstGlobal; + size_t iStringTableOffset; + size_t iStringTableSize; + SectionNumberMap iSectionNumberMap; + SectionVaddrAddendMap iSectionVaddrAddendMap; + ElfSymbolTableManager * iElfSymbolTableManager; + +}; + +class ElfSymTabStringTable : public ElfStringTable { +public: + ElfSymTabStringTable(ElfSymbolTableManager & aElfSymbolTableManager): + iElfSymbolTableManager(aElfSymbolTableManager) + {} + + virtual size_t Size(); + +private: + ElfSymbolTableManager & iElfSymbolTableManager; +}; + +class ElfSymbolTableManager : public FileFragmentOwner { +public: + ElfSymbolTableManager(Elf32Header & aElf32Header, E32RomImage & aRomImage, + OutputFile & aOutputFile, ElfSectionManager & aElfSectionManager) : + iElf32Header(aElf32Header), iRomImage(aRomImage), + iOutputFile(aOutputFile), iElfSectionManager(aElfSectionManager), + iData(NULL), + iSymbolStringTableSizeValid(false), + iSymbolStringTableSize(0), + iCurrentFragment(this), + iStringTable(*this) + {} + + // The FileFragmentOwner protocol + virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ); + virtual size_t Size(); + virtual void DeleteFileFragmentData(); + virtual void AddData(OutputFile & aOutputFile); + + void AddSymbolTable(String & aPath, size_t aOffset, size_t aSize, size_t aFirstGlobal){ + iCurrentFragment.AddSymbolTable(aPath, aOffset, aSize, aFirstGlobal); + } + void AddStringTable(String & aPath, size_t aOffset, size_t aSize){ + iCurrentFragment.AddStringTable(aPath, aOffset, aSize); + + } + virtual void AddSymbolFragment(){ + iSymbolFragments.push_back(iCurrentFragment); + } + virtual void AddSymbolTable(); + + size_t GetSymTabStringsSectionSize(); + + virtual void Finalize(SectionNumberMap & aSectionNumberMap, SectionVaddrAddendMap & aSectionVaddrAddendMap); + +private: + // Don't want one of these to be copied + ElfSymbolTableManager(const ElfSymbolTableManager & aElfSymbolTableManager); + + ElfSymbolTableManager & operator=(const ElfSymbolTableManager & aElfSymbolTableManager); + + size_t GetSymTabSectionSize(); + size_t GetFirstNonLocalIndex(); + +private: + typedef std::vector SymbolFragmentList; +private: + Elf32Header & iElf32Header; + E32RomImage & iRomImage; + OutputFile & iOutputFile; + ElfSectionManager & iElfSectionManager; + + char * iData; + bool iSymbolStringTableSizeValid; + size_t iSymbolStringTableSize; + ElfFileSymbolFragments iCurrentFragment; + SymbolFragmentList iSymbolFragments; + ElfSymTabStringTable iStringTable; +}; + +#endif /*ELFSYMBOLTABLEMANAGER_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/filefragment.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/filefragment.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include + +#include "filefragment.h" +#include "outputfile.h" + + +FileFragmentData::~FileFragmentData(){ + +} + +FileFragmentOwner::~FileFragmentOwner(){ + +} + +FileFragment::~FileFragment(){ + +} + +void FileFragment::Write(OutputFile * aFile){ + FileFragmentData aData; + iOwner->GetFileFragmentData(aData); + assert(aData.GetSize() == iSize); + aFile->Write(iOffset, iSize, aData.GetData()); + iOwner->DeleteFileFragmentData(); +} + +void FileFragmentOwner::AddData(OutputFile & aOutputFile){ + const FileFragment & aFileFrag = aOutputFile.GetFileFragment(this); + SetOffset(aFileFrag.GetOffset()); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/filefragment.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/filefragment.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,116 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef FILEFRAGMENT_H_ +#define FILEFRAGMENT_H_ + +#include + +class OutputFile; + +class FileFragmentData +{ + +public: + FileFragmentData() : + iSize(0), iData(0) + {}; + FileFragmentData(size_t aSize, char * aData) : + iSize(aSize), iData(aData) + {}; + virtual ~FileFragmentData(); + inline char* GetData() { return iData; }; + inline size_t GetSize() { return iSize; }; + inline void SetData(char * newVal) { iData = newVal; }; + inline void SetSize(size_t newVal) { iSize = newVal; }; + +private: + size_t iSize; + char* iData; +}; + +/** + * Defines the interface for owners of FileFragments + */ +class FileFragmentOwner +{ +public: + FileFragmentOwner() : + iOffset(0) + {}; + + FileFragmentOwner(size_t aOffset) : + iOffset(aOffset) + {}; + + virtual ~FileFragmentOwner(); + + virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ) =0; + virtual size_t Size() = 0; + virtual void DeleteFileFragmentData() = 0; + + virtual void AddData(OutputFile & aFile); + virtual size_t GetOffset() { return iOffset; } + virtual void SetOffset(size_t aOffset) { iOffset = aOffset; } + +//protected: + void SetFileFragmentData(FileFragmentData & aFileFragmentData, size_t aSize, char * aData){ + aFileFragmentData.SetSize(aSize); + aFileFragmentData.SetData(aData); + } + +protected: + size_t iOffset; +}; + + +/** + * Represents a fragment of file of a given size (in bytes) at a given offset (in + * bytes). + */ +class FileFragment +{ + +public: + FileFragment(size_t aOffset, size_t aSize, FileFragmentOwner * aOwner) : + iOffset(aOffset), iSize(aSize), iOwner(aOwner) + {}; + virtual ~FileFragment(); + + inline size_t GetOffset() const { return iOffset; }; + inline size_t GetSize() const { return iSize; }; + inline void SetOffset(size_t newVal) { iOffset = newVal; }; + inline void SetSize(size_t newVal) { iSize = newVal; }; + void Write(OutputFile * aFile); + +private: + /** + * offset in bytes at which the fragment occurs in the file + */ + size_t iOffset; + /** + * size in bytes of the file fragment + */ + size_t iSize; + /** + * the owner of the file fragment + */ + FileFragmentOwner * iOwner; +}; + +#endif /*FILEFRAGMENT_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/inputfile.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/inputfile.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,112 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include +#include +#include + +#include "elfromerror.h" +#include "inputfile.h" + +InputFile & InputFile::operator=(const InputFile & aInputFile) { + // Don't copy fd. Force a new to be got. + iOpened = false; + // Force size to be re-computed + iSizeValid = false; + iOffset = aInputFile.iOffset; + iPathName = aInputFile.iPathName; + return *this; +} + +InputFile::InputFile(const InputFile & aInputFile){ + *this = aInputFile; +} + +InputFile::~InputFile(){ + Close(); +} + +void InputFile::Open(){ + if (iOpened) return; + if ((iFd = open(iPathName.c_str(), O_RDONLY|O_BINARY, 0)) < 0) + errx(EX_NOINPUT, "open \"%s\" failed\n", iPathName.c_str()); + else + iOpened = true; +} + +void InputFile::Close(){ + if (!iOpened) return; + close(iFd); + iOpened = false; + iSizeValid = false; +} + +size_t InputFile::Size(){ + if (iSizeValid) return iSize - iOffset; + SetSize(); + return iSize - iOffset; +} + +void InputFile::SetSize(){ + Open(); + if ((iSize = lseek(iFd, (size_t)0, SEEK_END)) == (size_t)-1) + errx(EX_NOINPUT, "failed to get size of \"%s\"", iPathName.c_str()); + if (lseek(iFd, (size_t)0, SEEK_SET) != 0) + errx(EX_NOINPUT, "failed to get size of \"%s\"", iPathName.c_str()); + Close(); + iSizeValid = true; +} + +char * InputFile::GetData(){ + size_t nbytes = Size(); + return GetData(nbytes); +} + +char * InputFile::GetData(size_t nbytes) { + char * data = new char[nbytes]; + GetData(data, nbytes); + return data; +} + +void InputFile::GetData(void * data, size_t nbytes){ + char * d = (char *)data; + size_t done = 0; + ssize_t n; + + Open(); + + if (iOffset > 0) + if ((size_t)lseek(iFd, iOffset, SEEK_SET) != iOffset) { + Close(); + errx(EX_NOINPUT, "failed to read from \"%s\"", iPathName.c_str()); + } + + while (nbytes){ + n = read(iFd, d+done,nbytes); + // n must be greater than 0 + if (n <= 0){ + Close(); + errx(EX_NOINPUT, "failed to read from \"%s\"", iPathName.c_str()); + } + done += n; + nbytes -= n; + } + + Close(); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/inputfile.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/inputfile.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef INPUTFILE_H_ +#define INPUTFILE_H_ + +#include + +#include "defs.h" + +class InputFile { +public: + InputFile(PathName & aPath) : + iPathName(aPath), iFd(0), iOpened(false), iSize(0), iSizeValid(false), iOffset(0) + { + assert(iPathName.size() != 0); + } + ~InputFile(); + void Open(); + void Close(); + size_t Size(); + char * GetData(); + char * GetData(size_t nbytes); + void GetData(void * data, size_t nbytes); + void SetOffset(size_t aOffset) { iOffset = aOffset; } + size_t GetOffset() { return iOffset; } + + InputFile & operator=(const InputFile & aInputFile); + InputFile(const InputFile & aInputFile); + + +private: + + void SetSize(); +private: + PathName iPathName; + int iFd; + bool iOpened; + size_t iSize; + bool iSizeValid; + size_t iOffset; +}; + +#endif /*INPUTFILE_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/main.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include "romdetails.h" +#include "processoptions.h" + +#include "elfromerror.h" +#include "elfrom.h" + + +void InitLibElf() { + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EX_SOFTWARE, "ELF library initialization failed: %s\n", + elf_errmsg(-1)); +} + +RomDetails * Init(int argc, char * argv[]){ + RomDetails * details = ProcessOptions(argc, argv); + return ProcessRomDetails(details); +} + +int main(int argc, char * argv[]){ +//TODO: print banner if trace on + InitLibElf(); + RomDetails * romDetails = Init(argc, argv); + ElfRom aElfRom(romDetails); + aElfRom.SetupE32RomData(); + aElfRom.SetupELFRomData(); + aElfRom.AddData(); + + aElfRom.Dump(); + + return EXIT_SUCCESS; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/outputfile.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/outputfile.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,125 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "outputfile.h" + +static const size_t NumReservedFileFragments = 100; + +OutputFile::OutputFile(PathName aFileName) : + iFileName(aFileName), iOpened(false), iFd(-1), iCurrentOffset(0) +{ + assert(iFileName.size() != 0); + // reserve space for file fragments + iFileFragments.reserve(NumReservedFileFragments); +} + +OutputFile::~OutputFile(){ + iFileFragments.clear(); + if (iOpened) + Close(); +} + + +void OutputFile::Close(){ + if (iOpened) { + close(iFd); + iOpened = false; + } +} + +void OutputFile::Flush(){ + if (!iOpened) + Open(); + if (iFileFragments.size() > 0) { + FragmentList::iterator aFrag = iFileFragments.begin(); + FragmentList::iterator end = iFileFragments.end(); + while (aFrag != end) { + aFrag->Write(this); + aFrag++; + } + iFileFragments.clear(); + } +} + +void OutputFile::Dump(){ + Flush(); + Close(); +} + +const FileFragment & OutputFile::GetFileFragment(FileFragmentOwner * aOwner){ + size_t aSize = aOwner->Size(); + FileFragment aFragment(iCurrentOffset, aSize, aOwner); + iFileFragments.push_back(aFragment); + iCurrentOffset += ALIGN4(aSize); + return iFileFragments.back(); +} + +void OutputFile::Open(){ + if (!iOpened) { + if ((iFd = open(iFileName.c_str(), O_WRONLY | O_CREAT | O_BINARY | O_TRUNC, S_IRUSR | S_IWUSR)) == -1) { + char msg[1000]; + sprintf(msg, "Output file %s", iFileName.c_str()); + perror(msg); + exit(EXIT_FAILURE); + } + iOpened = true; + } +} + +void OutputFile::Write(size_t aOffset, size_t aSize, char * aData){ + assert(((aSize==0) && (aData==NULL)) || ((aSize>0) && (aData!=NULL))); + if (aSize == 0) return; + char msg[1000]; +#ifndef USE_PWRITE + if (lseek(iFd, aOffset, SEEK_SET) != (int)aOffset) { + sprintf(msg, "Failed to seek to offset %d in output file %s", aOffset, iFileName.c_str()); + goto error; + } + for (size_t n = 0; n < aSize;) { + if ((int)(n += write(iFd, aData+n, aSize - n)) == -1) { + sprintf(msg, "Failed to write to output file %s", iFileName.c_str()); + goto error; + } + } +#else + for (size_t n = 0; n < aSize;) { + if ((n += pwrite(iFd, aData+n, aSize - n, aOffset + n)) == -1) { + sprintf(msg, "Failed to write to output file %s", iFileName.c_str()); + goto error; + } + } +#endif + return; + +error: + perror(msg); +// should we close the file and delete it?? +#ifdef DELETE_OUTPUT_ON_ERROR + Close(); + unlink(iFileName); +#endif + exit(EXIT_FAILURE); +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/outputfile.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/outputfile.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef OUTPUTFILE_H_ +#define OUTPUTFILE_H_ + +#include + +#include "defs.h" +#include "filefragment.h" + +// uncomment this is output file should be deleted on error +//#define DELETE_OUTPUT_ON_ERROR +// uncomment to use pwrite (this should be more efficient) but results in different +// file pointer behaviour. NB not defined by MINGW in unistd.h +//#define USE_PWRITE + +// TODO: NB currently this can only deal with 4gb files. Need to upgrade for larger files +class OutputFile +{ +public: + OutputFile(PathName aFileName); + virtual ~OutputFile(); + + virtual void Close(); + virtual void Flush(); + virtual void Dump(); + virtual const FileFragment & GetFileFragment(FileFragmentOwner * aOwner); + virtual void Open(); + virtual void Write(size_t aOffset, size_t aSize, char * aData); + virtual size_t Size(){ return iCurrentOffset; } + +private: + // Don't want one of these to be copied + OutputFile(const OutputFile & aOutputFile); + + OutputFile & operator=(const OutputFile & aOutputFile); + +private: + typedef std::vector FragmentList; + + PathName iFileName; + FragmentList iFileFragments; + bool iOpened; + int iFd; + size_t iCurrentOffset; + +}; + +#endif /*OUTPUTFILE_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/processoptions.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/processoptions.cpp Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,609 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +namespace po = boost::program_options; +#include +#include +namespace fs = boost::filesystem; + +#include + +#include +#include +#include +#include + +#include +#include + +using namespace std; + +#include "defs.h" +#include "romdetails.h" +#include "inputfile.h" +#include "elfromerror.h" + +static inline void downcase(std::string & s){ + for (std::string::iterator i = s.begin(); i != s.end(); i++) + *i = tolower(*i); +} + +static int required_option(const po::variables_map& vm, const char* option){ + if (vm.count(option) == 0 || vm[option].defaulted()) { + cerr << "Error: option \'" << option << "\' required.\n"; + return 1; + } + return 0; +} + +static int either_or_required(const po::variables_map& vm, const char* option1, const char* option2){ + if ((vm.count(option1) == 0 || vm[option1].defaulted()) && + (vm.count(option2) == 0 || vm[option2].defaulted())) { + cerr << "Error: either option \'" << option1 << "\' or option \'" << option2 <<"\' required.\n"; + return 1; + } + return 0; +} + +RomDetails * ProcessOptions(int ac, char* av[]) { + RomDetails * details = new RomDetails; + int errors = 0; + + try { + + string phys_addr; + po::options_description desc(" Command Line Only"); + desc.add_options() + ("help,h", "produce help message") + ("config-file,c", po::value(), "pathname of config file " + "(overrides default of elf4rom.cfg and value " + "of ELF4ROM_CFG_FILE environment variable)") + ; + + po::options_description config(" Command Line and Configuration File"); + config.add_options() + ("board-name,b", po::value(&details->iBoardName), "name of board targeted e.g. versatilepb") + ("debug,d", po::value< vector >(&details->iTargetFiles)->multitoken()->composing(), + "collect ELF and DWARF data from the listed files") + ("drive,D", po::value(&details->iDrive), "drive on which to find ELF files") + ("exclude,e", po::value< vector >(&details->iExcludeFiles)->multitoken()->composing(), + "exclude collection of ELF and DWARF data from the listed files") + ("input,i", po::value(&details->iRomFile), "pathname of ROM image") + ("logfile,l", po::value(&details->iLogFile), "pathname of ROMBUILD log file") + ("no-dwarf,n", po::bool_switch(&details->iNoDwarf), "suppress generatation of DWARF in output" + " (prevents source level debugging but saves time and space)") + ("output,o", po::value(&details->iElfRomFile), "pathname of output file") + // lexical_cast doesn't understand even though its just a typedef + // for unsigned int + ("physical-address,p", po::value(&phys_addr), "physical address of ROM on device. Overrides board-name") + ("search,s", po::bool_switch(&details->iSearch), "search for ELF files in build directory if .sym file not " + "found in release directory") + ("strip,S", po::bool_switch(&details->iStrip), "suppress generation of symbol table and DWARF in output" + " (useful to produce a 'loadable' ELF image for e.g. a simulator)") + ("trace,t", po::bool_switch(&details->iTrace), "switch on trace") + ; + + po::options_description cmdline_options; + cmdline_options.add(desc).add(config); + + po::options_description config_file_options; + config_file_options.add(config); + + po::variables_map vm; + //po::store(po::parse_command_line(ac, av, desc), vm); + po::store(po::command_line_parser(ac, av).options(cmdline_options).run(), vm); + + char * cfgFile = "elf4rom.cfg"; + if (vm.count("config-file")) { + char * xcfgFile = (char *)(vm["config-file"].as().c_str()); + fs::path cfgpath(xcfgFile); + + if (fs::exists(cfgpath)) { + cfgFile = xcfgFile; + } else { + cerr << "Warning: specified config file " << xcfgFile << " not found: will not attempt to use default.\n"; + } + } else { + char * envCfgFile = getenv("ELF4ROM_CFG_FILE"); + if (envCfgFile != NULL) + cfgFile = envCfgFile; + } + + ifstream ifs(cfgFile); + store(parse_config_file(ifs, config_file_options), vm); + + po::notify(vm); + + if (vm.count("help")) { + cout << "elf4rom [option]"; + cout << cmdline_options << "\n"; + delete details; + exit(EXIT_SUCCESS) ; + } + + + errors += required_option(vm, "input"); + errors += required_option(vm, "logfile"); + errors += required_option(vm, "output"); + + errors += either_or_required(vm, "board-name", "physical-address"); + + if (vm.count("physical-address")){ + char *f; + const char * p = phys_addr.c_str(); + details->iRomPhysAddr = strtoul(p ,&f , 16); + if (f == p){ + cerr << "Error: invalid arg to --physical-address: " << phys_addr.c_str() << "\n"; + exit(EXIT_FAILURE); + } + } else if (vm.count("board-name")){ + // TODO: figure out address frmo board name + cerr << "Error: --board-name option not implemented yet\n"; + exit(EXIT_FAILURE) ; + } + + if (errors) { + cerr << "elf4rom [option]"; + cerr << cmdline_options << "\n"; + delete details; + exit(EXIT_FAILURE) ; + } + } + catch(exception& e) { + cerr << "error: " << e.what() << "\n"; + exit(EXIT_FAILURE) ; + } + catch(...) { + cerr << "Exception of unknown type!\n"; + exit(EXIT_FAILURE) ; + } + + return details; +} + + +static bool VerifyLogFile(string::const_iterator & start, string::const_iterator & end, string::const_iterator & rest){ +#if 0 +// Look for somthing like the following +ROMBUILD - Rom builder V2.08 (Build 593) +Copyright (c) 1996-2007 Symbian Software Ltd. +or +ROMBUILD - Rom builder V2.08 (Build 596) +Copyright (c) 1996-2009 Nokia Corporation. +#endif + + const char * banner = "ROMBUILD.*Rom builder.*Copyright.*"; + boost::regex e(banner); + boost::match_results what; + if (boost::regex_search(start, end, what, e)){ + rest = what[0].second; + return true; + } + return false; +} + +static void OffenceWarning (string & offender){ + cerr << "Warning: The following section of the ROM Log appears corrupt:\n" << offender << "\n"; +} + +static inline unsigned int ConvertToUnsignedLong(string & s, string & offender){ + char * endp; + const char * ss = s.c_str(); + unsigned int res = strtoul(ss, &endp,16); + if (endp == ss) + OffenceWarning(offender); + return res; +} + +static bool ProcessXIPFile(string::const_iterator & start, string::const_iterator & end, + string::const_iterator & rest, RomDetails * details){ + const char * f = + "Processing file (\\S+)\\s*" // 1 + "(\\[Primary\\]\\s*)?" // 2 + "(\\[Secondary\\]\\s*)?" // 3 + "(ELF File:\\s*\\S+\\s*)?" // 4 + "(ELF MD5:\\s*\\S+\\s*)?" // 5 + "Load Address:\\s+(\\S+)\\s*" // 6 + "Size:\\s+\\S+\\s*" + "Uids:\\s+\\S+\\s+\\S+\\s+\\S+\\s+\\S+\\s*" + "Entry point:\\s+\\S+\\s*" + "Code start addr:\\s+(\\S+)\\s*" // 7 + "Data start addr:\\s+(\\S+)\\s*" // 8 + "DataBssLinearBase:\\s+(\\S+)\\s*" // 9 + "Text size:\\s+\\S+\\s*" + "Code size:\\s+(\\S+)\\s*" // 10 + "Data size:\\s+(\\S+)\\s*" // 11 + "BssSize:\\s+(\\S+)\\s*" // 12 + ; + boost::regex e(f); + boost::match_results what; + if (boost::regex_search(start, end, what, e)){ + string filename(what[1].first, what[1].second); + string offender(what[0].first, what[0].second); + if (filename.size() == 0) + OffenceWarning(offender); + bool primary = what[2].matched; + if (what[2].matched){ + primary = true; + } + + const int kla = 6; + string ls(what[kla].first, what[kla].second); + LinearAddr load = ConvertToUnsignedLong(ls, offender); + + const int kta = kla + 1; + string ts(what[kta].first, what[kta].second); + LinearAddr text = ConvertToUnsignedLong(ts, offender); + + const int kda = kta + 1; + string ds(what[kda].first, what[kda].second); + LinearAddr data = ConvertToUnsignedLong(ds, offender); + + const int kva = kda + 1; + string vds(what[kva].first, what[kva].second); + VirtualAddr vdata = ConvertToUnsignedLong(vds, offender); + + const int kts = kva + 1; + string tss(what[kts].first, what[kts].second); + size_t textSize = ConvertToUnsignedLong(tss, offender); + + const int kds = kts + 1; + string dss(what[kds].first, what[kds].second); + size_t fileDataSize = ConvertToUnsignedLong(dss, offender); + + const int kbs = kds + 1; + string bsss(what[kbs].first, what[kbs].second); + size_t bssSize = ConvertToUnsignedLong(bsss, offender); + VirtualAddr bss = vdata + fileDataSize; + size_t memDataSize = fileDataSize + bssSize; + + string elffile(""); + details->iXIPFiles.push_back(XIPFileDetails(filename, + elffile, + load, + text, + textSize, + vdata, + fileDataSize, + data, + bss, + memDataSize)); + if (primary) + new(&details->iPrimary)XIPFileDetails(filename, + elffile, + load, + text, + textSize, + vdata, + fileDataSize, + data, + bss, + memDataSize); + + rest = what[0].second; + return true; + } + rest = start; + return false; + +} + +static void CheckXIPFiles(RomDetails * details, std::vector & list){ + for (std::vector::iterator i = list.begin(); i != list.end(); i++) { + bool found = false; + for (RomDetails::XIPFileList::iterator j = details->iXIPFiles.begin(); j != details->iXIPFiles.end(); j++){ + fs::path e32filePath(j->iE32File); + String e32FileName(e32filePath.leaf()); + if ((*i) == e32FileName){ + found = true; + break; + } + + } + if (!found){ + cerr << "WARNING: " << (*i) << " not found in ROM\n"; + } + } +} + +static void CheckDebugXIPFiles(RomDetails * details){ + CheckXIPFiles(details, details->iTargetFiles); +} + +static void CheckExcludeXIPFile(RomDetails * details){ + CheckXIPFiles(details, details->iExcludeFiles); +} + +static void ProcessXIPFiles(string::const_iterator & start, string::const_iterator & end, + string::const_iterator & rest, RomDetails * details){ + while (ProcessXIPFile(start,end,rest,details)){ + start = rest; + } + CheckDebugXIPFiles(details); + CheckExcludeXIPFile(details); +} + + +static void ProcessRomDetails(string::const_iterator & start, string::const_iterator & end, + string::const_iterator & rest, RomDetails * details){ + const char * align = "Linear base address:\\s*([\\S]+)$"; + boost::regex e(align); + boost::match_results what; + if (boost::regex_search(start, end, what, e)){ + string offender(what[0].first, what[0].second); + string lbas(what[1].first, what[1].second); + details->iRomBaseLinearAddr = ConvertToUnsignedLong(lbas, offender); + } else { + cerr << "Error: " << details->iLogFile << " not a valid ROM log file. Could not find Linear base address." << "\n"; + exit(EXIT_FAILURE) ; + } +} + +static fs::path FindBuildPath(RomDetails * details){ + const string epoc32("epoc32"); + const string builddir("build"); + const string epocRoot(getenv("EPOCROOT")); + if (details->iDrive.size() > 0) { + string drive(details->iDrive); + if (drive.size() == 1){ + drive += ":"; + } else if (((drive.size() == 2) && (drive[drive.size()-1] != ':')) || (drive.size() > 2)){ + cerr << "Error: Invalid drive specification: " << drive << "\n"; + exit(EXIT_FAILURE) ; + } + fs::path buildpath(drive); + + buildpath /= epocRoot; + buildpath /= epoc32; + buildpath /= builddir; + return buildpath; + } + fs::path primary_path(details->iPrimary.iE32File); + fs::path buildpath; + for (fs::path::iterator i = primary_path.begin(); i != primary_path.end(); i++){ + string item(*i); + downcase(item); + buildpath /= item; + if (item == epoc32) { + buildpath /= builddir; + break; + } + } + return buildpath; +} + +class PathCache { +public: + typedef std::map PathMap; + + PathCache(fs::path & apath): + iBuildPath(apath) + { + if (fs::exists(apath)){ + fs::recursive_directory_iterator i(apath); + iCurrent = i; + } + } + bool FindPath(string & pattern, string & result); + fs::path & GetBuildPath() { return iBuildPath; } + +private: + bool GetNextPath(string & path); + bool Filtered(fs::path & path); + +private: + + fs::path iBuildPath; + fs::recursive_directory_iterator iCurrent; + fs::recursive_directory_iterator iEnd; + PathMap iPathMap; + static const std::string filters; +}; + + + +bool PathCache::Filtered(fs::path & apath){ + std::string ext(fs::extension(apath)); + downcase(ext); + if (ext.size() > 0){ + if (filters.find(ext) != std::string::npos) + return true; + } + return false; +} + +bool PathCache::GetNextPath(string & path){ + for (; iCurrent != iEnd; ++iCurrent ){ + if (fs::is_directory(iCurrent->status())) + continue; + fs::path candidate(iCurrent->path()); + if (!Filtered(candidate)) { + path = candidate.string(); + ++iCurrent; + return true; + } + } + return false; +} + +static void GetTarget(string & source, string & target){ + fs::path t1(source); + fs::path::iterator s = t1.begin(); + fs::path::iterator start = t1.end(); + int n = 0; + for (; n < 3 && s != start; n++, start--){} + if (n < 3) { + warnx(0, "%s does not have 3 elements\n", source.c_str()); + } + + fs::path q; + for (; start != t1.end(); start++){ + q /= fs::path(*start); + } + target = q.string(); + downcase(target); +} + +bool PathCache::FindPath(string & source, string & result){ + string ss; + if (source.size() == 0) return false; + GetTarget(source, ss); + + // now check the cache + PathMap::iterator res = iPathMap.find(ss); + if (res != iPathMap.end()){ + result = res->second; + return true; + } + + // otherwise iterate until we find a match + string candidate; + while (GetNextPath(candidate)){ + downcase(candidate); + size_t n = candidate.rfind(ss); + if (n != string::npos){ + size_t csize = candidate.size(); + size_t sssize = ss.size(); + if ((csize - sssize) == n){ + // put it in cache anyway just in case its the primary + iPathMap[ss] = candidate; + result = candidate; + return true; + } + } + string x; + GetTarget(candidate, x); + iPathMap[x] = candidate; + } + return false; +} + +const std::string PathCache::filters( + ".cpp" + ".h" + ".mk" + ".o" + ".in" + ".via" + ".mbg" + ".rsg" + ".bat" + ".make" + ".def" + ".armv5" + ); + +static bool FindSymFile(XIPFileDetails & detail, string & rootname){ + fs::path buildpath(rootname); + fs::path e32path(detail.iE32File); + buildpath /= e32path; + // check for pre-RAPTOR .sym file + fs::path elfpath = fs::change_extension(buildpath, ".sym"); + if (fs::exists(elfpath)) { + detail.iElfFile = elfpath.string(); + return true; + } + // check for RAPTOR .sym file + fs::path symPath(buildpath.string() + ".sym"); + if (fs::exists(symPath)) { + detail.iElfFile = symPath.string(); + return true; + } + return false; +} + +static void FindElfFile(XIPFileDetails & detail, PathCache & cache, bool search){ + // see if there's a .sym file + string root(cache.GetBuildPath().root_name()); + if (FindSymFile(detail, root)) return; + if (!search) { + cerr << "Warning: could not find ELF file for " << detail.iE32File << ".\n"; + return; + } + string s(detail.iE32File); + string res; + if (s.size() == 0) return; + if (cache.GetBuildPath().string().empty()) return; + + if (cache.FindPath(s, res)){ + detail.iElfFile = res; + } else + cerr << "Warning: could not find ELF file for " << detail.iE32File << ".\n"; +} + + +static void FindElfFiles(RomDetails * details){ + fs::path buildroot = FindBuildPath(details); + PathCache cache(buildroot); + bool search = details->iSearch; + FindElfFile(details->iPrimary, cache, search); + for(RomDetails::XIPFileList::iterator i = details->iXIPFiles.begin(); i != details->iXIPFiles.end(); i++){ + fs::path e32filePath(i->iE32File); + String e32FileName(e32filePath.leaf()); + if (details->iTargetFiles.empty()) { + bool find = true; + for (std::vector::iterator ef = details->iExcludeFiles.begin(); ef != details->iExcludeFiles.end(); ef++) { + fs::path excludePath(*ef); + String excludeFile(excludePath.leaf()); + if (e32FileName == excludeFile) { + find = false; + break; + } + } + if (find) + FindElfFile(*i, cache, search); + } else { + for (std::vector::iterator tf = details->iTargetFiles.begin(); tf != details->iTargetFiles.end(); tf++) { + fs::path targetPath(*tf); + String targetFile(targetPath.leaf()); + if (e32FileName == targetFile) { + FindElfFile(*i, cache, search); + break; + } + } + } + } + +} + +RomDetails * ProcessRomDetails(RomDetails * details){ + InputFile in(details->iLogFile); + char * data = in.GetData(); + string logfile(data); + string::const_iterator start = logfile.begin(); + string::const_iterator end = logfile.end(); + string::const_iterator rest; + + if (!VerifyLogFile(start, end , rest)) { + cerr << "error: " << details->iLogFile << " not a valid ROM log file." << "\n"; + exit(EXIT_FAILURE) ; + } + + ProcessXIPFiles(start,end,rest,details); + + ProcessRomDetails(rest, end, rest, details); + + FindElfFiles(details); + + // TODO: make sure functions that return data allocated with new [] + // have an appropriate return value so that delete [] can be used + delete [] data; + + return details; +} diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/processoptions.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/processoptions.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef PROCESSOPTIONS_H_ +#define PROCESSOPTIONS_H_ + +RomDetails * ProcessOptions(int ac, char* av[]); +RomDetails * ProcessRomDetails(RomDetails *); + +#endif /*PROCESSOPTIONS_H_*/ diff -r 2c1e559d48bf -r f24810eebc6b tools/elf4rom/src/romdetails.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/romdetails.h Tue Apr 06 17:00:22 2010 +0100 @@ -0,0 +1,151 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef ROMDETAILS_H_ +#define ROMDETAILS_H_ + +#include + +#include "defs.h" + +class XIPFileDetails { +public: + XIPFileDetails(): + iE32File(""), + iElfFile(""), + iLoadAddr(0x0), + iROAddr(0x0), + iROSize(0), + iRWAddr(0x0), + iRWSize(0), + iROMDataAddr(0), + iBSSAddr(0), + iBSSDataSize(0), + iElfTextBase(0), + iElfTextLimit(0), + iElfDataBase(0), + iRVCTProduced(false), + iGCCProduced(false) + {}; + XIPFileDetails(PathName & aE32File,PathName & aELFFile, LinearAddr load, LinearAddr text, size_t textSize, + VirtualAddr data, size_t dataSize, LinearAddr aRomData, VirtualAddr bss, + size_t bssDataSize): + iE32File(aE32File), + iElfFile(aELFFile), + iLoadAddr(load), + iROAddr(text), + iROSize(textSize), + iRWAddr(data), + iRWSize(dataSize), + iROMDataAddr(aRomData), + iBSSAddr(bss), + iBSSDataSize(bssDataSize), + iElfTextBase(0), + iElfTextLimit(0), + iElfDataBase(0), + iRVCTProduced(false), + iGCCProduced(false) + {}; + XIPFileDetails(char * aE32File,char * aELFFile, LinearAddr load, LinearAddr text, size_t textSize, + VirtualAddr data, size_t dataSize, LinearAddr aRomData, VirtualAddr bss, + size_t bssDataSize): + iE32File(aE32File), + iElfFile(aELFFile), + iLoadAddr(load), + iROAddr(text), + iROSize(textSize), + iRWAddr(data), + iRWSize(dataSize), + iROMDataAddr(aRomData), + iBSSAddr(bss), + iBSSDataSize(bssDataSize), + iElfTextBase(0), + iElfTextLimit(0), + iElfDataBase(0), + iRVCTProduced(false), + iGCCProduced(false) + {}; + + LinearAddr Relocate(LinearAddr addr){ + if ((addr >= iElfTextBase) && (addr < iElfTextLimit)){ + size_t offset = addr - iElfTextBase; + return iROAddr + offset; + } else if ((addr >= iElfDataBase) && (addr < (iElfDataBase + iBSSDataSize))) { + size_t offset = addr - iElfDataBase; + return iRWAddr + offset; + } else { + return addr; + } + } + PathName iE32File; + PathName iElfFile; + LinearAddr iLoadAddr; + LinearAddr iROAddr; + size_t iROSize; + VirtualAddr iRWAddr; + size_t iRWSize; + LinearAddr iROMDataAddr; + VirtualAddr iBSSAddr; + size_t iBSSDataSize; + VirtualAddr iElfTextBase; + VirtualAddr iElfTextLimit; + VirtualAddr iElfDataBase; + // This is dodgy. We probably need a better way of coping with 'oddities' + bool iRVCTProduced; + bool iGCCProduced; +}; + +class RomDetails { +public: + RomDetails(): + iBoardName(""), + iRomFile(""), + iElfRomFile(""), + iLogFile(""), + iDrive(""), + iRomPhysAddr(0), + iRomBaseLinearAddr(0), + iKernelDataVirtualAddr(0), + iNoDwarf(false), + iSearch(false), + iStrip(false), + iTrace(false), + iVerbosity(0) + {} + + typedef std::vector XIPFileList; + String iBoardName; + PathName iRomFile; + PathName iElfRomFile; + PathName iLogFile; + PathName iDrive; + LinearAddr iRomPhysAddr; + LinearAddr iRomBaseLinearAddr; + VirtualAddr iKernelDataVirtualAddr; + XIPFileDetails iPrimary; + XIPFileList iXIPFiles; + bool iNoDwarf; + bool iSearch; + bool iStrip; + bool iTrace; + unsigned int iVerbosity; + std::vector iTargetFiles; + std::vector iExcludeFiles; + +}; +#endif /*ROMDETAILS_H_*/