Migrate amdgpu-windows-interop to rocm-systems (#808)

Цей коміт міститься в:
Joseph Macaranas
2025-09-05 10:32:44 -04:00
зафіксовано GitHub
джерело 3d9d35a1f8
коміт 5ca7af2d30
261 змінених файлів з 86831 додано та 2 видалено
+3
Переглянути файл
@@ -0,0 +1,3 @@
/config.local
/tmp
/cache
+6
Переглянути файл
@@ -0,0 +1,6 @@
[core]
autostage = true
remote = storage
['remote "storage"']
url = s3://therock-dvc/rocm-systems
allow_anonymous_login = true
+3
Переглянути файл
@@ -0,0 +1,3 @@
# Add patterns of files dvc should ignore, which could improve
# the performance. Learn more at
# https://dvc.org/doc/user-guide/dvcignore
+4
Переглянути файл
@@ -62,6 +62,10 @@
- changed-files:
- any-glob-to-any-file: 'projects/roctracer/**/*'
"shared: amdgpu-windows-interop":
- changed-files:
- any-glob-to-any-file: 'shared/amdgpu-windows-interop/**/*'
documentation:
- changed-files:
- any-glob-to-any-file:
+46 -2
Переглянути файл
@@ -19,7 +19,7 @@ To limit your local checkout to only the project(s) you work on and improve perf
git clone --no-checkout --filter=blob:none https://github.com/ROCm/rocm-systems.git
cd rocm-systems
git sparse-checkout init --cone
git sparse-checkout set projects/rocblas shared/tensile
git sparse-checkout set projects/rocprofiler-sdk shared/rocprofiler-compute
git checkout develop # or the branch you are starting from
```
@@ -33,7 +33,7 @@ The checkout command of the two projects lasted less than 90 seconds.
If your work involves changing projects or introducing new projects, you can update your sparse-checkout environment:
```bash
git sparse-checkout set projects/hipsparse projects/rocsparse
git sparse-checkout set projects/hip projects/clr projects/hip-tests
```
This keeps your working directory clean and fast, as you won't need to clone the entire super-repo.
@@ -130,6 +130,50 @@ Please refer to [this documentation](/docs/continuous-integration.md) for furthe
---
## Large File Storage
[Data Version Control](https://dvc.org) is the system for large file storage in this super-repo. It provides staging capabilities on top of what Git LFS typically provides that ROCm CI/CD workflows can make use of. Files are stored in an AWS S3 bucket that has public-read access.
Currently, `dvc` utilization is limited to the `pal` libraries in the `shared/amdgpu-windows-interop` directory.
If your development does not involve these files, you do not need to install `dvc`.
### Installing DVC
`dvc` can be installed as a python module via pip and is cross-platform. Visit the [dvc installation page](https://dvc.org/doc/install) if you want to use another method of installation. Due to our use of an AWS S3 bucket with `dvc`, the `dvc[s3]` module should be installed. The configuration to download the large files from the AWS S3 bucket is already set in this repository.
```bash
pip install dvc[s3]
```
### Retrieving large files:
```bash
git pull
dvc pull
```
### Switching to versions in other branches or commits:
```bash
git checkout feature-branch
dvc checkout
```
### Update large files
Write-access requires authentication. Please reach out to a project lead for credentials. To make updates to files maintained by `DVC`:
```bash
dvc add [path-to-large-file-modified]
dvc push
git status
git add [dvc-files-mentioned-from-status-output]
git commit -m "commit message"
git push
```
---
## Gardener Rotation
In order to achieve the goal of keeping the `develop` branch healthy, a team of ROCm engineers will be dedicated towards monitoring and triaging issues that arise.
+198
Переглянути файл
@@ -0,0 +1,198 @@
AMD Software End User License Agreement
IMPORTANT-READ CAREFULLY: DO NOT INSTALL, COPY OR USE THE ENCLOSED SOFTWARE,
DOCUMENTATION (AS DEFINED BELOW), OR ANY PORTION THEREOF, UNTIL YOU HAVE
CAREFULLY READ AND AGREED TO THE FOLLOWING TERMS AND CONDITIONS. THIS IS A LEGAL
AGREEMENT ("AGREEMENT") BETWEEN YOU (EITHER AN INDIVIDUAL OR AN ENTITY) ("YOU")
AND ADVANCED MICRO DEVICES, INC. ("AMD").
IF YOU DO NOT AGREE TO THE TERMS OF THIS AGREEMENT, DO NOT INSTALL, COPY OR USE
THIS SOFTWARE. BY INSTALLING, COPYING OR USING THE SOFTWARE YOU AGREE TO ALL THE
TERMS AND CONDITIONS OF THIS AGREEMENT.
1. DEFINITIONS
1. “Derivative Works” means any work, revision, modification or adaptation made to or
derived from the Software, or any work that incorporates the Software, in whole or in
part.
2. “Documentation” means install scripts and online or electronic documentation
associated, included, or provided in connection with the Software, or any portion
thereof.
3. “Free Software License” means an open source or other license that requires, as a
condition of use, modification or distribution, that any resulting software must be (a)
disclosed or distributed in source code form; (b) licensed for the purpose of making
derivative works; or (c) redistributable at no charge.
4. “Intellectual Property Rights” means all copyrights, trademarks, trade secrets, patents,
mask works, and all related, similar, or other intellectual property rights recognized in
any jurisdiction worldwide, including all applications and registrations with respect
thereto.
5. “Object Code” means machine readable computer programming code files, which is not
in a human readable form.
6. “Software” means the enclosed AMD software program or any portion thereof that is
provided to You.
7. “Source Code” means computer programming code in human readable form and
related system level documentation, including all comments, symbols and any
procedural code such as job control language.
2. LICENSE
Subject to the terms and conditions of this Agreement, AMD hereby grants You a non-exclusive,
royalty-free, revocable, non-transferable, limited, copyright license to
1. install and use the Software solely in Object Code form in conjunction with systems or
components that include or incorporate AMD products, as applicable;
2. create Derivative Works solely in Object Code form of the Software for use with systems
or components that include or incorporate AMD products, as applicable;
3. unless otherwise prohibited by a confidentiality agreement, make and distribute copies
of the Derivative Works to Your partners and customers for use in conjunction with
systems or components that include or incorporate AMD products, provided that such
distribution shall be under a license agreement with terms and conditions at least as
restrictive as those set forth in the Agreement; and
4. use and reference the Documentation, if any, solely in connection with the Software and
Derivative Works.
3. RESTRICTIONS
Except for the limited license expressly granted in Section 2 herein, You have no other rights in
the Software, whether express, implied, arising by estoppel or otherwise. Further restrictions
regarding Your use of the Software are set forth below. Except for the limited license expressly
granted in Section 2, You may not:
1. modify or create derivative works of the Software or Documentation;
2. distribute, publish, display, sublicense, assign or otherwise transfer the Software or
Documentation;
3. decompile, reverse engineer, disassemble or otherwise reduce the Software to Source
Code form (except as allowed by applicable law);
4. alter or remove any copyright, trademark or patent notice(s) in the Software or
Documentation; or
5. use the Software and Documentation to: (i) develop inventions directly derived from
Confidential Information to seek patent protection; (ii) assist in the analysis of Your
patents and patent applications; or (iii) modify existing patents; or
6. use, modify and/or distribute any of the Software or Documentation so that any part
becomes subject to a Free Software License.
4. THIRD-PARTY COMPONENTS
The Software or Documentation may come bundled with third party technologies for which You
must obtain licenses from parties other than AMD (“Third Party Components”). By accessing
and using the Software or Documentation, You are agreeing to fully comply with the terms of
the applicable Third Party Component license. To the extent that a Third Party Component
license conflicts with the terms and conditions of this Agreement, then the Third Party
Component license shall control solely with respect to the applicable Third Party Component.
To the extent that any Third Party Components in the Software or Documentation requires an
offer for corresponding source code, AMD hereby makes such an offer for corresponding
source code form.
5. PRE-PRODUCTION SOFTWARE
The Software may be a pre-production version, intended to provide advance access to features
that may or may not eventually be included into production version of the Software.
Accordingly, pre-production Software may not be fully functional relative to production
versions of the Software. Use of pre-production Software may result in unexpected results, loss
of data, project delays or other unpredictable damage or loss. Pre-production Software is not
intended for use in production, and Your use of pre-production Software is at Your own risk.
6. FEEDBACK
You have no obligation to give AMD any suggestions, comments or other feedback
(“Feedback”) relating to the Software or Documentation. However, AMD may use and include
any Feedback that it receives from You to improve the Software, Documentation, or other AMD
products, software, and technologies. Accordingly, for any Feedback You provide to AMD, You
grant AMD and its affiliates and subsidiaries a worldwide, non-exclusive, irrevocable,royaltyfree,
perpetual license to, directly or indirectly, use, reproduce, license, sublicense, distribute,
make, have made, sell and otherwise commercialize the Feedback in the Software,
Documentation, or other AMD products, software and technologies. You further agree not to
provide any Feedback that (a) You know is subject to any Intellectual Property Rights of any
third party or (b) is subject to license terms which seek to require any products incorporating or
derived from such Feedback, or other AMD intellectual property, to be licensed to or otherwise
shared with any third party.
7. OWNERSHIP AND COPYRIGHT OF SOFTWARE
The Software, including all Intellectual Property Rights therein, and the Documentation are and
remain the sole and exclusive property of AMD or its licensors, and You shall have no right, title
or interest therein except as expressly set forth in this Agreement.
8. WARRANTY DISCLAIMER
THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND. AMD DISCLAIMS ALL WARRANTIES, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING BUT
NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, TITLE, NON-INFRINGEMENT, THAT THE SOFTWARE OR DOCUMENTATION WILL RUN
UNINTERRUPTED OR ERROR-FREE OR WARRANTIES ARISING FROM CUSTOM OF TRADE OR
COURSE OF USAGE. THE ENTIRE RISK ASSOCIATED WITH THE USE OF THE SOFTWARE AND
DOCUMENTATION IS ASSUMED BY YOU. Some jurisdictions do not allow the exclusion of
implied warranties, so the above exclusion may not apply to You.
9. LIMITATION OF LIABILITY AND INDEMNIFICATION
AMD AND ITS LICENSORS WILL NOT, UNDER ANY CIRCUMSTANCES BE LIABLE TO YOU FOR ANY
PUNITIVE, DIRECT, INCIDENTAL, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING
FROM USE OF THE SOFTWARE, DOCUMENTATION, OR THIS AGREEMENT EVEN IF AMD AND ITS
LICENSORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. In no event shall
AMD's total liability to You for all damages, losses, and causes of action (whether in contract,
tort (including negligence) or otherwise) exceed the amount of $100 USD. You agree to defend,
indemnify and hold harmless AMD and its licensors, and any of their directors, officers,
employees, affiliates or agents from and against any and all loss, damage, liability and other
expenses (including reasonable attorneys' fees), resulting from Your use of the Software,
Documentation, or violation of the terms and conditions of this Agreement.
10. EXPORT RESTRICTIONS
You shall adhere to all applicable U.S. import/export laws and regulations, as well as the
import/export control laws and regulations of other countries as applicable. You further agree
to not export, re-export, or transfer, directly or indirectly, any product, technical data, software
or source code received from AMD under this license, or the direct product of such technical
data or software to any country for which the United States or any other applicable
government requires an export license or other governmental approval without first obtaining
such licenses or approvals; or in violation of any applicable laws or regulations of the United
States or the country where the technical data or software was obtained. You acknowledge the
technical data and software received will not, in the absence of authorization from U.S. or local
law and regulations as applicable, be used by or exported, re-exported or transferred to: (i) any
sanctioned or embargoed country, or to nationals or residents of such countries; (ii) any
restricted end-user as identified on any applicable government end-user list; or (iii) any party
where the end-use involves nuclear, chemical/biological weapons, rocket systems, or
unmanned air vehicles. For the most current Country Group listings, or for additional
information about the EAR or Your obligations under those regulations, please refer to the U.S.
Bureau of Industry and Securitys website at http://www.bis.doc.gov/.
11. NOTICE TO U.S. GOVERNMENT END USERS
The Software and Documentation are "commercial items", as that term is defined at 48 C.F.R.
§2.101, consisting of "commercial computer software" and "commercial computer software
documentation", as such terms are used in 48 C.F.R. §12.212 and 48 C.F.R. §227.7202,
respectively. Consistent with 48 C.F.R. §12.212 or 48 C.F.R. §227.7202-1 through 227.7202-4, as
applicable, the commercial computer software and commercial computer software
documentation are being licensed to U.S. Government end users (a) only as commercial items
and (b) with only those rights as are granted to all other end users pursuant to the terms and
conditions set forth in this Agreement. Unpublished rights are reserved under the copyright
laws of the United States.
12. TERMINATION OF LICENSE
This Agreement will terminate immediately without notice from AMD or judicial resolution if (1)
You fail to comply with any provisions of this Agreement, or (2) You provide AMD with notice
that You would like to terminate this Agreement. Upon termination of this Agreement, You
must delete or destroy all copies of the Software. Upon termination or expiration of this
Agreement, all provisions survive except for Section 2.
13. SUPPORT AND UPDATES
AMD is under no obligation to provide any kind of support under this Agreement. AMD may, in
its sole discretion, provide You with updates to the Software and Documentation, and such
updates will be covered under this Agreement.
14. GOVERNING LAW
This Agreement is made under and shall be construed according to the laws of the State of
California, excluding conflicts of law rules. Each party submits to the jurisdiction of the state
and federal courts of Santa Clara County and the Northern District of California for the purposes
of this Agreement. You acknowledge that Your breach of this Agreement may cause irreparable
damage and agree that AMD shall be entitled to seek injunctive relief under this Agreement, as
well as such further relief as may be granted by a court of competent jurisdiction.
15. PRIVACY
We may be required under applicable data protection law to provide you with certain
information about who we are, how we process your personal data and for what purposes and
your rights in relation to your personal information and how to exercise them. This information
is provided in www.amd.com/en/corporate/privacy. It is important that you read that
information. AMDs Cookie Policy, sets out information about the cookies AMD uses.
16. GENERAL PROVISIONS
You may not assign this Agreement without the prior written consent of AMD and any
assignment without such consent will be null and void. The parties do not intend that any
agency or partnership relationship be created between them by this Agreement. Each
provision of this Agreement shall be interpreted in such a manner as to be effective and valid
under applicable law. However, in the event that any provision of this Agreement becomes or
is declared unenforceable by any court of competent jurisdiction, such provision shall be
deemed deleted and the remainder of this Agreement shall remain in full force and effect.
17. ENTIRE AGREEMENT
This Agreement sets forth the entire agreement and understanding between the parties with
respect to the Software and supersedes and merges all prior oral and written agreements,
discussions and understandings between them regarding the subject matter of this
Agreement. No waiver or modification of any provision of this Agreement shall be binding
unless made in writing and signed by an authorized representative of each party.
+26
Переглянути файл
@@ -0,0 +1,26 @@
##
########################################################################################################################
#
# Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
#
########################################################################################################################
cmake_minimum_required(VERSION 3.10)
file(GLOB sources
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
)
add_library(clCompilerElfLoader ${sources})
add_subdirectory(utils)
include_directories(${lib})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${elf-toolchain}/common)
if(WIN32)
include_directories(${elf-toolchain}/common/win32)
endif()
include_directories(${elf-toolchain}/libelf)
add_definitions(-DBSD_LIBELF)
Різницю між файлами не показано, бо вона завелика Завантажити різницю
+416
Переглянути файл
@@ -0,0 +1,416 @@
/*
************************************************************************************************************************
*
* Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
*
***********************************************************************************************************************/
//
// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved.
//
#ifndef ELF_HPP_
#define ELF_HPP_
#include <map>
#include "top.hpp"
#include "elf_utils.hpp"
#if !defined(WITH_LIGHTNING_COMPILER)
#include "caltarget.h" // using CALtargetEnum
#endif // !defined(WITH_LIGHTNING_COMPILER)
#include "libelf.h"
#include "gelf.h"
// Not sure where to put these in the libelf
#define AMD_BIF2 2 // AMD BIF Version 2.0
#define AMD_BIF3 3 // AMD BIF Version 3.0
// These two definitions need to stay in sync with
// the definitions elfdefinitions.h until they get
// properly upstreamed to gcc/libelf.
#ifndef EM_HSAIL
#define EM_HSAIL 0xAF5A
#endif
#ifndef EM_HSAIL_64
#define EM_HSAIL_64 0xAF5B
#endif
#ifndef EM_AMDIL
#define EM_AMDIL 0x4154
#endif
#ifndef EM_ATI_CALIMAGE_BINARY
#define EM_ATI_CALIMAGE_BINARY 125
#endif
#ifndef EM_AMDGPU
#define EM_AMDGPU 224
#endif
#ifndef ELFOSABI_AMD_OPENCL
#define ELFOSABI_AMD_OPENCL 201
#endif
#ifndef ELFOSABI_HSAIL
#define ELFOSABI_HSAIL 202
#endif
#ifndef ELFOSABI_AMDIL
#define ELFOSABI_AMDIL 203
#endif
#ifndef ELFOSABI_CALIMAGE
#define ELFOSABI_CALIMAGE 100
#endif
namespace amd {
// Test: is it ELF file (with a given bitness) ?
bool isElfHeader(const char* p, signed char ec);
bool isElfMagic(const char* p);
// Test: is it ELF for CAL ?
bool isCALTarget(const char* p, signed char ec);
// Symbol handle
typedef struct symbol_handle *Sym_Handle;
class OclElf
{
public:
enum {
CAL_BASE = 1001, // A number that is not dependent on libelf.h
CPU_BASE = 2001,
CPU_FEATURES_FIRST = 0, // Never generated, but keep it for simplicity.
CPU_FEATURES_LAST = 0xF // This should be consistent with cpudevice.hpp
} oclElfBase;
typedef enum {
// NOTE!!! Never remove an entry or change the order.
#if !defined(WITH_LIGHTNING_COMPILER)
// All CAL targets are within [CAL_FIRST, CAL_LAST].
CAL_FIRST = CAL_TARGET_600 + CAL_BASE,
CAL_LAST = CAL_TARGET_LAST + CAL_BASE,
#endif // !defined(WITH_LIGHTNING_COMPILER)
// All CPU targets are within [CPU_FIRST, CPU_LAST]
CPU_FIRST = CPU_FEATURES_FIRST + CPU_BASE,
CPU_LAST = CPU_FEATURES_LAST + CPU_BASE,
OCL_TARGETS_LAST,
} oclElfTargets;
typedef enum {
CAL_PLATFORM = 0,
CPU_PLATFORM = 1,
COMPLIB_PLATFORM = 2,
LC_PLATFORM = 3,
LAST_PLATFORM = 4
} oclElfPlatform;
typedef enum {
LLVMIR = 0,
SOURCE,
ILTEXT,
ASTEXT,
CAL,
DLL,
STRTAB,
SYMTAB,
RODATA,
SHSTRTAB,
NOTES,
COMMENT,
ILDEBUG,
DEBUG_INFO,
DEBUG_ABBREV,
DEBUG_LINE,
DEBUG_PUBNAMES,
DEBUG_PUBTYPES,
DEBUG_LOC,
DEBUG_ARANGES,
DEBUG_RANGES,
DEBUG_MACINFO,
DEBUG_STR,
DEBUG_FRAME,
JITBINARY,
CODEGEN,
TEXT,
INTERNAL,
SPIR,
SPIRV,
RUNTIME_METADATA,
OCL_ELF_SECTIONS_LAST
} oclElfSections;
typedef struct {
char* sec_name; //! section name
char* sec_addr; //! section address
uint64_t sec_size; //! section size
char* sym_name; //! symbol name
char* address; //! address of corresponding to symbol data
uint64_t size; //! size of data corresponding to symbol
} SymbolInfo;
private:
// file descriptor
int _fd;
// file name
const char* _fname;
// pointer to libelf structure
::Elf* _e;
// Error Object
mutable OclElfErr _err;
// Bitness of the Elf object.
unsigned char _eclass;
// Raw ELF bytes in memory from which Elf object is initialized
// The memory is owned by the client, not this OclElf object !
const char* _rawElfBytes;
uint64_t _rawElfSize;
// Read, write, or read and write for this Elf object
const Elf_Cmd _elfCmd;
// Memory management
typedef std::map<void*, size_t> EMemory;
EMemory _elfMemory;
// Indexes of .shstrtab and .strtab (for convenience)
Elf64_Word _shstrtab_ndx;
Elf64_Word _strtab_ndx;
public:
/*
OclElf object can be created for reading or writing (it could be created for
both reading and writing, which is not supported yet at this time). Currently,
it has two forms:
1) OclElf(eclass, rawElfBytes, rawElfSize, 0, ELF_C_READ)
To load ELF from raw bytes in memory and generate OclElf object. And this
object is for reading only.
2) OclElf(eclass, NULL, 0, elfFileName|NULL, ELF_C_WRITE)
To create an ELF for writing and save it into a file 'elfFileName' (if it
is NULL, the OclElf will create a temporary file and set it to 'elfFileName'.
Since we need to read the ELF into memory, this file 'elfFileName' is created
with both read and write, so that the runtime can use dumpImage() to get ELF
raw bytes by reading this file.
'eclass' is ELF's bitness and it must be the same as the eclass of ELF to
be loaded (for example, rawElfBytes).
Return values of all public APIs with bool return type
true : on success;
false : on error.
*/
OclElf (
unsigned char eclass, // eclass for this ELF
const char* rawElfBytes, // raw ELF bytes to be loaded
uint64_t rawElfSize, // size of the ELF raw bytes
const char* elfFileName, // File to save this ELF.
Elf_Cmd elfcmd // ELF_C_READ/ELF_C_WRITE
);
~OclElf ();
/*
dumpImage() will finalize the ELF and write it into the file. It then reads
it into the memory; and returns it via <buff, len>.
The memory pointed by buff is owned by OclElf object.
*/
bool dumpImage(char** buff, size_t* len);
/*
addSection() is used to create a single ELF section with data <d_buf, d_size>. If
do_copy is true, the OclElf object will make a copy of d_buf and uses that copy to
create an ELF section.
When setting do_copy = false, the caller should make sure that <d_buf, d_size> will
be unchanged and available during the lifetime of this OclElf object; ie before
calling dumpImage().
*/
bool addSection (
oclElfSections id,
const void* d_buf,
size_t d_size,
bool do_copy = true
);
/*
getSection() will return the whole section in <dst, sz>.
The memory pointed by <dst, sz> is owned by the OclElf object.
*/
bool getSection(oclElfSections id, char** dst, size_t* sz) const;
/*
addSymbol() adds a symbol with name 'symbolName' and data <buffer, size>
into the ELF. 'id' indicates which section <buffer, size> will go
into. The meaning of 'do_copy' is the same as addSection().
*/
bool addSymbol(
oclElfSections id, // Section in which symbol is added
const char* symbolName, // Name of symbol
const void* buffer, // Symbol's data
size_t size, // Symbol's size
bool do_copy = true // If true, add a copy of buffer into the section
);
/*
* getSymbol() will return the data associated with
* the symbol from the Elf.
*
* The memory pointed by <buffer, size> is owned by the OclElf object
*/
bool getSymbol(
oclElfSections id, // Section in which symbol is in
const char* symbolName, // Name of the symbol to retrieve
char** buffer, // Symbol's data
size_t* size // Symbol's size
) const;
/*
nextSymbol() and getSymbolInfo() use the symbol handle to access symbols
For example:
for( Sym_Handle s = nextSymbol(NULL); s ; s = nextSymbol(s)) {
SymbolInfo si;
if (!getSymbolInfo(s, &si)) {
Error;
}
use si
}
where nextSymbol(NULL) will return the first symbol.
Note that memory space pointed to by si is owned by OclElf.
*/
bool getSymbolInfo(Sym_Handle sym, SymbolInfo* symInfo) const;
Sym_Handle nextSymbol(Sym_Handle symhandle) const;
/*
Adds a note with name 'noteName' and description "noteDesc"
into the .note section of ELF. Length of note name is 'nameSize'.
Length of note description is "descSize'.
*/
bool addNote(const char* noteName, const char* noteDesc,
size_t nameSize, size_t descSize);
/*
Returns the description of a note whose name is 'noteName'
in 'noteDesc'.
Returns the length of the description in 'descSize'.
*/
bool getNote(const char* noteName, char** noteDesc, size_t *descSize);
/*
Get/set machine and platform (target) for which elf is built.
*/
bool getTarget(uint16_t& machine, oclElfPlatform& platform);
bool setTarget(uint16_t machine, oclElfPlatform platform);
/*
Get/set elf type field from header
*/
bool getType(uint16_t &type);
bool setType(uint16_t type);
/*
Get/set elf flag field from header.
*/
bool getFlags(uint32_t &flag);
bool setFlags(uint32_t flag);
/*
Clear() will return the status of OclElf to just after ctor() is invoked.
However, it will not regenerate a temporary file name like ctor() does.
It is useful when the ELF content needs to be discarded for some reason.
*/
bool Clear();
bool hasError() { return (_err.getOclElfError())[0] != 0; }
const char* getErrMsg() { return _err.getOclElfError(); }
unsigned char getELFClass() { return _eclass; }
bool isHsaCo() const { return (_eclass == ELFCLASS32) ?
(elf32_getehdr(_e)->e_machine == EM_AMDGPU) : (elf64_getehdr(_e)->e_machine == EM_AMDGPU); }
private:
/* Initialization */
bool Init();
/*
Initialize ELF object by creating ELF header and key sections such as
.shstrtab, .strtab, and .symtab.
*/
bool InitElf ();
// Wraper for creating a section header and Elf_Data
bool createShdr (
oclElfSections id,
Elf_Scn*& scn,
Elf64_Word shname,
Elf64_Word shlink = 0
);
Elf_Data* createElfData(
Elf_Scn*& scn,
oclElfSections id,
void* d_buf,
uint64_t d_size,
bool do_copy
);
/*
Create a new section (id) with data <d_buf, d_size>. If do_copy is true,
make a copy of d_buf and create a new section with that copy.
Return the valid Elf_Scn on success; return NULL on error.
Note that newSection() uses Section Header's size, so make sure elf_update()
is invoked properly before invoking newSection().
*/
Elf_Scn* newSection (
oclElfSections id,
const void* d_buf,
size_t d_size,
bool do_copy = true // if true, add a copy of d_buf
);
/*
Add a new data into a section by creating a new data descriptor.
And the new data's offset is returned in 'outOffset'.
*/
bool addSectionData(
Elf64_Xword& outOffset,
oclElfSections id,
const void* buffer,
size_t size,
bool do_copy=true // if true, add a copy of buffer
);
// Return Elf_Data for this section 'id'
bool getSectionData(Elf_Data*& data, oclElfSections id) const;
// Return Elf_Scn for this section 'id'
bool getSectionDesc(Elf_Scn*& scn, oclElfSections id) const;
//
bool getShstrtabNdx(Elf64_Word& outNdx, const char*);
void* oclelf_allocAndCopy(void* p, size_t sz);
void* oclelf_calloc(size_t sz);
void elfMemoryRelease();
};
} // namespace amd
#endif
+285
Переглянути файл
@@ -0,0 +1,285 @@
/*
************************************************************************************************************************
*
* Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
*
***********************************************************************************************************************/
//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//
#include "elf_utils.hpp"
#include "memfile.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
/*
See elf_utils.hpp for descriptions about each functions
*/
namespace amd {
#define ELF_OPEN mem_open
#define ELF_READ(f, b, l) mem_read((f), (b), (unsigned int)(l))
#define ELF_WRITE mem_write
#define ELF_CLOSE mem_close
#define ELF_LSEEK mem_lseek
/*
Save the error string in _lastErrMsg. If it is built without NDEBUG, the program
will terminate immediately with exit(1).
*/
void OclElfErr::xfail(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsnprintf(&_lastErrMsg[0], (size_t)MAX_ERROR_MESSAGE_LENGTH, fmt, ap);
va_end(ap);
#ifndef NDEBUG
printf("%s\n", _lastErrMsg);
exit(1);
#endif
}
namespace oclelfutils {
/*
Wrap malloc() with xfail(), so this returns newly-allocated memory or 0.
The memory is guaranteed to be initialized to zero.
*/
void* xmalloc(OclElfErr& err, const size_t len)
{
void *retval = calloc(1, len);
if (retval == NULL) {
err.xfail("xmalloc failed: out of memory");
return NULL;
}
return retval;
}
/*
Return file descriptor on success; return -1 on error and invoke xfail()
to record the error.
*/
int xopen(OclElfErr& err, const char *fname, const int in_flags, const int perms)
{
const int retval = ELF_OPEN(fname, in_flags, perms);
if (retval == -1) {
err.xfail("Failed to open '%s': %s", fname, strerror(errno));
return -1;
}
return retval;
}
/*
Return 0 on success; return -1 on error.
*/
int xclose(OclElfErr& err, const char *fname, const int fd)
{
int rc;
while ( ((rc = :: ELF_CLOSE(fd)) == -1) && (errno == EINTR) ) { ;/* spin. */ }
if (rc == -1) {
err.xfail("Failed to close '%s': %s", fname, strerror(errno));
return -1;
}
return rc;
}
/*
Return the file offset location on success; return -1 on error.
*/
off_t xlseek(
OclElfErr& err,
const char* fname,
const int fd,
const off_t offset,
const int whence)
{
// For really big file _lseeki64/lseek64 are needed. For now,
// lseek/_lseek is enough.
off_t res = ELF_LSEEK(fd, offset, whence);
if (res == -1) {
err.xfail("Failed to seek in '%s': %s", fname, strerror(errno));
return -1;
}
return res;
}
/*
Return the number of bytes that are read on success; return -1 on error.
*/
ssize_t xread(
OclElfErr& err,
const char* fname,
const int fd,
void* buf,
const size_t buf_len
)
{
ssize_t rc;
while (((rc = ELF_READ(fd, buf, buf_len)) == -1) && (errno == EINTR)) { ;/* spin */ }
if (rc < 0) {
err.xfail("Failed to read '%s': %s", fname, strerror(errno));
return -1;
}
return rc;
}
#if 0
/*
Return the number of bytes that have been written on success; return -1 on error.
*/
ssize_t xwrite(OclElfErr& err,
const char* fname,
const int fd,
const void* buf,
const size_t len)
{
ssize_t rc;
while (((rc = ELF_WRITE(fd, buf, len)) == -1) && (errno == EINTR)) { ;/* spin */ }
if ( (rc == -1) || (rc != (ssize_t)len) ) {
err.xfail("Failed to write '%s': %s", fname, strerror(errno));
return -1;
}
return rc;
}
/*
Allocate a copy of (str), invoke xfail() on failure.
Returns NULL on error, or address of the allocated copy
*/
char* xstrdup(OclElfErr& err, const char *str)
{
char* retval = (char*)xmalloc(err, strlen(str) + 1);
if (retval == NULL) {
err.xfail("xstrdup failed: cannot allocate new char string");
return NULL;
}
strcpy(retval, str);
return retval;
}
/*
get the length of an open file in bytes. return -1 on error.
*/
uint64_t xget_file_size(OclElfErr& err, const char *fname, const int fd)
{
struct stat statbuf;
if (fstat(fd, &statbuf) == -1) {
err.xfail("Failed to fstat '%s': %s", fname, strerror(errno));
return -1;
}
return (uint64_t) statbuf.st_size;
}
/*
Copy file 'infd' to file 'outfd'.
Return the total number of bytes copied on success; return -1 on error.
*/
int64_t xcopyfile(
OclElfErr& err,
const char* in,
const int infd,
const char* out,
const int outfd
)
{
uint64_t retval = 0;
ssize_t rc = 0;
off_t res = xlseek(err, in, infd, 0, SEEK_SET);
if (res == -1) {
err.xfail("xcopyfile failed in xlseek : in %s, out %s", in, out);
return -1;
}
uint8_t* copybuf = err._copyBuffer;
if (copybuf == NULL) {
copybuf = (uint8_t*)xmalloc(err, IO_BUF_SIZE);
err._copyBuffer = copybuf;
}
while ( (rc = xread(err, in, infd, copybuf, IO_BUF_SIZE)) > 0 ) {
retval += (uint64_t) rc;
int ret = xwrite(err, out, outfd, copybuf, rc);
if (ret == -1) {
err.xfail("xcopyfile failed in xwrite: in %s, out %s", in, out);
return -1;
}
}
if (rc == -1) {
err.xfail("xcopyfile failed in xread: in %s, out %s", in, out);
return -1;
}
return retval;
}
/*
Copy file from 'infd' to current offset in 'outfd', for 'size' bytes.
Return 'size' on success; return -1 on error.
*/
int64_t
xcopyfile_range(
OclElfErr& err, const char *in, const int infd,
const char *out, const int outfd,
const uint64_t offset, const uint64_t size
)
{
uint8_t* copybuf = err._copyBuffer;
if (copybuf == NULL) {
copybuf = (uint8_t*)xmalloc(err, IO_BUF_SIZE);
err._copyBuffer = copybuf;
}
ssize_t rc = xlseek(err, in, infd, (off_t) offset, SEEK_SET);
if (rc == -1) {
err.xfail("xcopyfile_range: xlseek() failed: %s", in);
return -1;
}
uint64_t remaining = size;
while (remaining >= IO_BUF_SIZE) {
rc = xread(err, in, infd, copybuf, IO_BUF_SIZE);
if ((rc == -1) || (rc != IO_BUF_SIZE)) {
err.xfail("xcopyfile_range: xread() failed %s", in);
return -1;
}
rc = xwrite(err, out, outfd, copybuf, IO_BUF_SIZE);
if (rc == -1) {
err.xfail("xcopyfile_range: xwrite() failed: %s", out);
}
remaining -= (uint64_t) IO_BUF_SIZE;
}
if (remaining > 0) {
rc = xread(err, in, infd, copybuf, IO_BUF_SIZE);
if ((rc == -1) || (rc != (ssize_t)remaining)) {
err.xfail("xcopyfile_range: xread() failed %s", in);
return -1;
}
rc = xwrite(err, out, outfd, copybuf, rc);
if (rc == -1) {
err.xfail("xcopyfile_range: xwrite() failed: %s", out);
}
}
return size;
}
uint64_t
align_to_page(const uint64_t offset)
{
// TODO_jugu don't use hardcoded pagesize.
return (offset + ((1LL << 12) -1)) & ((uint64_t)(-(1LL << 12)));
}
#endif
} // namespace elfutils
} // namespace amd
+150
Переглянути файл
@@ -0,0 +1,150 @@
/*
************************************************************************************************************************
*
* Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
*
***********************************************************************************************************************/
//
// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved.
//
#ifndef _ELF_UTILS_HPP
#define _ELF_UTILS_HPP
#include <cstdlib>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "top.hpp"
namespace amd {
#define MAX_ERROR_MESSAGE_LENGTH 1024
#define IO_BUF_SIZE 16 * 1024
class OclElfErr
{
public:
// Temperary buffer for copying from file to file
uint8_t* _copyBuffer; // Initialized first time it is used
private:
// Keep the last error message.
char _lastErrMsg[MAX_ERROR_MESSAGE_LENGTH];
public:
OclElfErr() : _copyBuffer(NULL) { _lastErrMsg[0] = 0; }
~OclElfErr() {
if (_copyBuffer) {
free(_copyBuffer);
}
}
void Init() { _lastErrMsg[0] = 0; }
void Fini() {
_lastErrMsg[0] = 0;
if (_copyBuffer) {
free(_copyBuffer);
}
_copyBuffer = NULL;
}
// Return the last error message.
const char* getOclElfError() const { return _lastErrMsg; }
//
// Save the error string in ErrorMessage. If it is built without NDEBUG, the program
// will terminate immediately with exit(1).
//
void xfail(const char *fmt, ...);
};
namespace oclelfutils {
/*
Wrap malloc() with xfail(), so this returns newly-allocated memory or 0.
The memory is guaranteed to be initialized to zero.
*/
void* xmalloc(OclElfErr& err, const size_t len);
/*
Return file descriptor on success; return -1 on error and invoke xfail()
to record the error.
*/
int xopen(OclElfErr& err, const char *fname, const int flags, const int perms);
/*
Return 0 on success; return -1 on error.
*/
int xclose(OclElfErr& err, const char *fname, const int fd);
/*
Return the file offset location on success; return -1 on error.
*/
off_t xlseek(OclElfErr& err, const char *fname, const int fd,
const off_t o, const int whence);
/*
Return the number of bytes that are read on success; return -1 on error.
*/
ssize_t xread(
OclElfErr& err,
const char* fname, // File name for file descriptor 'fd'
const int fd, // File descriptor
void* buf, // buffer for reading
const size_t buf_len // capacity of buffer in bytes
);
#if 0
/*
Return the number of bytes that have been written on success; return -1 on error.
*/
ssize_t xwrite(
OclElfErr& err,
const char* fname, // File name for file descriptor 'fd'
const int fd, // File descriptor
const void* buf, // data buffer to be written out
const size_t buf_len // the size of data in bytes
);
/*
Allocate a copy of (str), invoke xfail() on failure.
Returns 0 on error, or address of the allocated copy
*/
char* xstrdup(OclElfErr& err, const char *str);
/*
get the length of an open file in bytes. return -1 if error.
*/
uint64_t xget_file_size(OclElfErr& err, const char *fname, const int fd);
/*
Copy file 'infd' to file 'outfd'.
Return the total number of bytes copied on success; return -1 on error.
*/
int64_t xcopyfile(OclElfErr& err, const char *in, const int infd,
const char *out, const int outfd);
/*
Copy file from 'infd' to current offset in 'outfd', for 'size' bytes.
Return 'size' on success; return -1 on error.
*/
int64_t xcopyfile_range(OclElfErr& err, const char *in, const int infd,
const char *out, const int outfd,
const uint64_t offset, const uint64_t size);
// Align a value to the page size.
uint64_t align_to_page(const uint64_t offset);
#endif
} // namespace elfutils
} // namespace amd
#endif
+12
Переглянути файл
@@ -0,0 +1,12 @@
##
########################################################################################################################
#
# Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
#
########################################################################################################################
cmake_minimum_required(VERSION 3.10)
if(NOT TARGET oclelf)
add_subdirectory(libelf)
endif()
+539
Переглянути файл
@@ -0,0 +1,539 @@
/*-
* Copyright (c) 2009 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: _elftc.h 2064 2011-10-26 15:12:32Z jkoshy $
*/
/**
** Miscellanous definitions needed by multiple components.
**/
#ifndef _ELFTC_H
#define _ELFTC_H
#ifndef NULL
#define NULL ((void *) 0)
#endif
#ifndef offsetof
// change from (int) to (char *) for x64 gcc
#define offsetof(T, M) ((char *) &((T*) 0) -> M)
#endif
/*
* Supply macros missing from <sys/queue.h>
*/
#ifndef STAILQ_FOREACH_SAFE
#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = STAILQ_FIRST((head)); \
(var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
(var) = (tvar))
#endif
#ifndef STAILQ_LAST
#define STAILQ_LAST(head, type, field) \
(STAILQ_EMPTY((head)) ? \
NULL : \
((struct type *)(void *) \
((char *)((head)->stqh_last) - offsetof(struct type, field))))
#endif
#ifndef TAILQ_FOREACH_SAFE
#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = TAILQ_FIRST((head)); \
(var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
(var) = (tvar))
#endif
/*
* Symbols that are sometimes missing in system headers.
*/
#ifndef DT_DEPRECATED_SPARC_REGISTER
#define DT_DEPRECATED_SPARC_REGISTER 0x70000001
#endif
#ifndef DT_GNU_PRELINKED
#define DT_GNU_PRELINKED 0x6FFFFDF5U
#endif
#ifndef DT_GNU_CONFLICTSZ
#define DT_GNU_CONFLICTSZ 0x6FFFFDF6U
#endif
#ifndef DT_GNU_LIBLISTSZ
#define DT_GNU_LIBLISTSZ 0x6FFFFDF7U
#endif
#ifndef DT_GNU_HASH
#define DT_GNU_HASH 0x6FFFFEF5U
#endif
#ifndef DT_GNU_CONFLICT
#define DT_GNU_CONFLICT 0x6FFFFEF8U
#endif
#ifndef DT_GNU_LIBLIST
#define DT_GNU_LIBLIST 0x6FFFFEF9U
#endif
#ifndef DT_MAXPOSTAGS
#define DT_MAXPOSTAGS 34
#endif
#ifndef DT_SUNW_AUXILIARY
#define DT_SUNW_AUXILIARY 0x6000000D
#endif
#ifndef DT_SUNW_CAP
#define DT_SUNW_CAP 0x60000010
#endif
#ifndef DT_SUNW_FILTER
#define DT_SUNW_FILTER 0x6000000F
#endif
#ifndef DT_SUNW_RTLDINF
#define DT_SUNW_RTLDINF 0x6000000E
#endif
#ifndef DT_USED
#define DT_USED 0x7FFFFFFE
#endif
#ifndef ELFOSABI_86OPEN
#define ELFOSABI_86OPEN 5
#endif
#ifndef ELFOSABI_AIX
#define ELFOSABI_AIX 7
#endif
#ifndef ELFOSABI_HURD
#define ELFOSABI_HURD 4
#endif
#ifndef ELFOSABI_NONE
#define ELFOSABI_NONE 0
#endif
#ifndef ELFOSABI_NSK
#define ELFOSABI_NSK 14
#endif
#ifndef ELFOSABI_OPENVMS
#define ELFOSABI_OPENVMS 13
#endif
/*
* Supply missing EM_XXX definitions.
*/
#ifndef EM_68HC05
#define EM_68HC05 72
#endif
#ifndef EM_68HC08
#define EM_68HC08 71
#endif
#ifndef EM_68HC11
#define EM_68HC11 70
#endif
#ifndef EM_68HC16
#define EM_68HC16 69
#endif
#ifndef EM_ARCA
#define EM_ARCA 109
#endif
#ifndef EM_ARC_A5
#define EM_ARC_A5 93
#endif
#ifndef EM_AVR
#define EM_AVR 83
#endif
#ifndef EM_BLACKFIN
#define EM_BLACKFIN 106
#endif
#ifndef EM_CR
#define EM_CR 103
#endif
#ifndef EM_CRIS
#define EM_CRIS 76
#endif
#ifndef EM_D10V
#define EM_D10V 85
#endif
#ifndef EM_D30V
#define EM_D30V 86
#endif
#ifndef EM_F2MC16
#define EM_F2MC16 104
#endif
#ifndef EM_FIREPATH
#define EM_FIREPATH 78
#endif
#ifndef EM_FR30
#define EM_FR30 84
#endif
#ifndef EM_FX66
#define EM_FX66 66
#endif
#ifndef EM_HUANY
#define EM_HUANY 81
#endif
#ifndef EM_IP2K
#define EM_IP2K 101
#endif
#ifndef EM_JAVELIN
#define EM_JAVELIN 77
#endif
#ifndef EM_M32R
#define EM_M32R 88
#endif
#ifndef EM_MAX
#define EM_MAX 102
#endif
#ifndef EM_MMIX
#define EM_MMIX 80
#endif
#ifndef EM_MN10200
#define EM_MN10200 90
#endif
#ifndef EM_MN10300
#define EM_MN10300 89
#endif
#ifndef EM_MSP430
#define EM_MSP430 105
#endif
#ifndef EM_NS32K
#define EM_NS32K 97
#endif
#ifndef EM_OPENRISC
#define EM_OPENRISC 92
#endif
#ifndef EM_PDSP
#define EM_PDSP 63
#endif
#ifndef EM_PJ
#define EM_PJ 91
#endif
#ifndef EM_PRISM
#define EM_PRISM 82
#endif
#ifndef EM_SEP
#define EM_SEP 108
#endif
#ifndef EM_SE_C33
#define EM_SE_C33 107
#endif
#ifndef EM_SNP1K
#define EM_SNP1K 99
#endif
#ifndef EM_ST19
#define EM_ST19 74
#endif
#ifndef EM_ST200
#define EM_ST200 100
#endif
#ifndef EM_ST7
#define EM_ST7 68
#endif
#ifndef EM_ST9PLUS
#define EM_ST9PLUS 67
#endif
#ifndef EM_SVX
#define EM_SVX 73
#endif
#ifndef EM_TMM_GPP
#define EM_TMM_GPP 96
#endif
#ifndef EM_TPC
#define EM_TPC 98
#endif
#ifndef EM_UNICORE
#define EM_UNICORE 110
#endif
#ifndef EM_V850
#define EM_V850 87
#endif
#ifndef EM_VAX
#define EM_VAX 75
#endif
#ifndef EM_VIDEOCORE
#define EM_VIDEOCORE 95
#endif
#ifndef EM_XTENSA
#define EM_XTENSA 94
#endif
#ifndef EM_ZSP
#define EM_ZSP 79
#endif
#ifndef PN_XNUM
#define PN_XNUM 0xFFFFU
#endif
#ifndef R_IA_64_DIR32LSB
#define R_IA_64_DIR32LSB 0x25
#endif
#ifndef R_IA_64_DIR64LSB
#define R_IA_64_DIR64LSB 0x27
#endif
#ifndef R_IA_64_SECREL32LSB
#define R_IA_64_SECREL32LSB 0x65
#endif
#ifndef R_MIPS_32
#define R_MIPS_32 0x2
#endif
#ifndef R_PPC_ADDR32
#define R_PPC_ADDR32 0x1
#endif
#ifndef R_SPARC_UA32
#define R_SPARC_UA32 23
#endif
#ifndef R_SPARC_UA64
#define R_SPARC_UA64 54
#endif
#ifndef R_X86_64_32
#define R_X86_64_32 10
#endif
#ifndef R_X86_64_64
#define R_X86_64_64 1
#endif
#ifndef SHT_AMD64_UNWIND
#define SHT_AMD64_UNWIND 0x70000001
#endif
#ifndef SHT_SUNW_ANNOTATE
#define SHT_SUNW_ANNOTATE 0X6FFFFFF7
#endif
#ifndef SHT_SUNW_DEBUGSTR
#define SHT_SUNW_DEBUGSTR 0X6FFFFFF8
#endif
#ifndef SHT_SUNW_DEBUG
#define SHT_SUNW_DEBUG 0X6FFFFFF9
#endif
#ifndef SHT_SUNW_cap
#define SHT_SUNW_cap 0x6FFFFFF5
#endif
#ifndef SHT_SUNW_dof
#define SHT_SUNW_dof 0x6FFFFFF4
#endif
#ifndef SHT_SUNW_verdef
#define SHT_SUNW_verdef 0x6FFFFFFD
#endif
#ifndef SHT_SUNW_verneed
#define SHT_SUNW_verneed 0x6FFFFFFE
#endif
#ifndef SHT_SUNW_versym
#define SHT_SUNW_versym 0x6FFFFFFF
#endif
#ifndef SHN_XINDEX
#define SHN_XINDEX 0xFFFFU
#endif
#ifndef SHT_GNU_ATTRIBUTES
#define SHT_GNU_ATTRIBUTES 0x6FFFFFF5U
#endif
#ifndef SHT_GNU_HASH
#define SHT_GNU_HASH 0x6FFFFFF6U
#endif
#ifndef SHT_GNU_LIBLIST
#define SHT_GNU_LIBLIST 0x6FFFFFF7U
#endif
/*
* VCS Ids.
*/
#ifndef ELFTC_VCSID
#if defined(__FreeBSD__)
#define ELFTC_VCSID(ID) __FBSDID(ID)
#endif
#if defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)
#if defined(__GNUC__)
#define ELFTC_VCSID(ID) __asm__(".ident\t\"" ID "\"")
#else
#define ELFTC_VCSID(ID) /**/
#endif
#endif
#if defined(__NetBSD__)
#define ELFTC_VCSID(ID) __RCSID(ID)
#endif
#endif /* ELFTC_VCSID */
/*
* Provide an equivalent for getprogname(3).
*/
#ifndef ELFTC_GETPROGNAME
#if defined(__FreeBSD__) || defined(__NetBSD__)
#include <stdlib.h>
#define ELFTC_GETPROGNAME() getprogname()
#endif /* defined(__FreeBSD__) || defined(__NetBSD__) */
#if defined(__linux__)
#ifdef __cplusplus
extern "C" {
#endif
/*
* GLIBC based systems have a global 'char *' pointer referencing
* the executable's name.
*/
extern /*const*/ char *program_invocation_short_name;
#ifdef __cplusplus
}
#endif
#define ELFTC_GETPROGNAME() program_invocation_short_name
#endif /* __linux__ */
#endif /* ELFTC_GETPROGNAME */
/**
** Per-OS configuration.
**/
#if defined(__linux__)
#include <endian.h>
#define ELFTC_BYTE_ORDER __BYTE_ORDER
#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN __LITTLE_ENDIAN
#define ELFTC_BYTE_ORDER_BIG_ENDIAN __BIG_ENDIAN
/*
* Debian GNU/Linux is missing strmode(3).
*/
#define ELFTC_HAVE_STRMODE 0
/* Whether we need to supply {be,le}32dec. */
#define ELFTC_NEED_BYTEORDER_EXTENSIONS 1
#define roundup2 roundup
#endif /* __linux__ */
#if defined(__FreeBSD__)
#include <osreldate.h>
#include <sys/endian.h>
#define ELFTC_BYTE_ORDER _BYTE_ORDER
#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN
#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN
#define ELFTC_HAVE_STRMODE 1
#if __FreeBSD_version <= 900000
#define ELFTC_BROKEN_YY_NO_INPUT 1
#endif
#endif /* __FreeBSD__ */
#if defined(__NetBSD__)
#include <sys/endian.h>
#define ELFTC_BYTE_ORDER _BYTE_ORDER
#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN
#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN
#define ELFTC_HAVE_STRMODE 1
#define ELFTC_BROKEN_YY_NO_INPUT 1
#endif /* __NetBSD __ */
#endif /* _ELFTC_H */
Різницю між файлами не показано, бо вона завелика Завантажити різницю
@@ -0,0 +1,47 @@
#!/bin/sh
#
# $Id: native-elf-format 2064 2011-10-26 15:12:32Z jkoshy $
#
# Find the native ELF format for a host platform by compiling a
# test object and examining the resulting object.
#
# This script is used if there is no easy way to determine this
# information statically at compile time.
program=`basename $0`
tmp_c=`mktemp -u nefXXXXXX`.c
tmp_o=`echo ${tmp_c} | sed -e 's/.c$/.o/'`
trap "rm -f ${tmp_c} ${tmp_o}" 0 1 2 3 15
touch ${tmp_c}
echo "/* Generated by ${program} on `date` */"
cc -c ${tmp_c} -o ${tmp_o}
readelf -h ${tmp_o} | awk '
$1 ~ "Class:" {
sub("ELF","",$2); elfclass = $2;
}
$1 ~ "Data:" {
if (match($0, "little")) {
elfdata = "LSB";
} else {
elfdata = "MSB";
}
}
$1 ~ "Machine:" {
if (match($0, "Intel.*386")) {
elfarch = "EM_386";
} else if (match($0, ".*X86-64")) {
elfarch = "EM_X86_64";
} else {
elfarch = "unknown";
}
}
END {
printf("#define ELFTC_CLASS ELFCLASS%s\n", elfclass);
printf("#define ELFTC_ARCH %s\n", elfarch);
printf("#define ELFTC_BYTEORDER ELFDATA2%s\n", elfdata);
}'
@@ -0,0 +1,14 @@
/*
************************************************************************************************************************
*
* Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
*
***********************************************************************************************************************/
#if !defined(_LP64)
#define ELFTC_CLASS ELFCLASS32
#else
#define ELFTC_CLASS ELFCLASS64
#endif
#define ELFTC_ARCH EM_386
#define ELFTC_BYTEORDER ELFDATA2LSB
+906
Переглянути файл
@@ -0,0 +1,906 @@
/*
Copyright (c) 2003-2011, Troy D. Hanson http://uthash.sourceforge.net
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* $Id: uthash.h 2064 2011-10-26 15:12:32Z jkoshy $ */
#ifndef UTHASH_H
#define UTHASH_H
#include <string.h> /* memcmp,strlen */
#include <stddef.h> /* ptrdiff_t */
#include <stdlib.h> /* exit() */
/* These macros use decltype or the earlier __typeof GNU extension.
As decltype is only available in newer compilers (VS2010 or gcc 4.3+
when compiling c++ source) this code uses whatever method is needed
or, for VS2008 where neither is available, uses casting workarounds. */
#ifdef _MSC_VER /* MS compiler */
#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */
#define DECLTYPE(x) (decltype(x))
#else /* VS2008 or older (or VS2010 in C mode) */
#define NO_DECLTYPE
#define DECLTYPE(x)
#endif
#else /* GNU, Sun and other compilers */
#define DECLTYPE(x) (__typeof(x))
#endif
#ifdef NO_DECLTYPE
#define DECLTYPE_ASSIGN(dst,src) \
do { \
char **_da_dst = (char**)(&(dst)); \
*_da_dst = (char*)(src); \
} while(0)
#else
#define DECLTYPE_ASSIGN(dst,src) \
do { \
(dst) = DECLTYPE(dst)(src); \
} while(0)
#endif
/* a number of the hash function use uint32_t which isn't defined on win32 */
#ifdef _MSC_VER
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
#else
#include <inttypes.h> /* uint32_t */
#endif
#define UTHASH_VERSION 1.9.4
#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */
#define uthash_malloc(sz) malloc(sz) /* malloc fcn */
#define uthash_free(ptr,sz) free(ptr) /* free fcn */
#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */
#define uthash_expand_fyi(tbl) /* can be defined to log expands */
/* initial number of buckets */
#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */
#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */
#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */
/* calculate the element whose hash handle address is hhe */
#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
#define HASH_FIND(hh,head,keyptr,keylen,out) \
do { \
unsigned _hf_bkt,_hf_hashv; \
out=NULL; \
if (head) { \
HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \
if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \
HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \
keyptr,keylen,out); \
} \
} \
} while (0)
#ifdef HASH_BLOOM
#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM)
#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0)
#define HASH_BLOOM_MAKE(tbl) \
do { \
(tbl)->bloom_nbits = HASH_BLOOM; \
(tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \
if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \
memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \
(tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \
} while (0);
#define HASH_BLOOM_FREE(tbl) \
do { \
uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \
} while (0);
#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8)))
#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8)))
#define HASH_BLOOM_ADD(tbl,hashv) \
HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
#define HASH_BLOOM_TEST(tbl,hashv) \
HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
#else
#define HASH_BLOOM_MAKE(tbl)
#define HASH_BLOOM_FREE(tbl)
#define HASH_BLOOM_ADD(tbl,hashv)
#define HASH_BLOOM_TEST(tbl,hashv) (1)
#endif
#define HASH_MAKE_TABLE(hh,head) \
do { \
(head)->hh.tbl = (UT_hash_table*)uthash_malloc( \
sizeof(UT_hash_table)); \
if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \
memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \
(head)->hh.tbl->tail = &((head)->hh); \
(head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \
(head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \
(head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \
(head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \
HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \
memset((head)->hh.tbl->buckets, 0, \
HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
HASH_BLOOM_MAKE((head)->hh.tbl); \
(head)->hh.tbl->signature = HASH_SIGNATURE; \
} while(0)
#define HASH_ADD(hh,head,fieldname,keylen_in,add) \
HASH_ADD_KEYPTR(hh,head,&add->fieldname,keylen_in,add)
#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \
do { \
unsigned _ha_bkt; \
(add)->hh.next = NULL; \
(add)->hh.key = (char*)keyptr; \
(add)->hh.keylen = keylen_in; \
if (!(head)) { \
head = (add); \
(head)->hh.prev = NULL; \
HASH_MAKE_TABLE(hh,head); \
} else { \
(head)->hh.tbl->tail->next = (add); \
(add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \
(head)->hh.tbl->tail = &((add)->hh); \
} \
(head)->hh.tbl->num_items++; \
(add)->hh.tbl = (head)->hh.tbl; \
HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \
(add)->hh.hashv, _ha_bkt); \
HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \
HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \
HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \
HASH_FSCK(hh,head); \
} while(0)
#define HASH_TO_BKT( hashv, num_bkts, bkt ) \
do { \
bkt = ((hashv) & ((num_bkts) - 1)); \
} while(0)
/* delete "delptr" from the hash table.
* "the usual" patch-up process for the app-order doubly-linked-list.
* The use of _hd_hh_del below deserves special explanation.
* These used to be expressed using (delptr) but that led to a bug
* if someone used the same symbol for the head and deletee, like
* HASH_DELETE(hh,users,users);
* We want that to work, but by changing the head (users) below
* we were forfeiting our ability to further refer to the deletee (users)
* in the patch-up process. Solution: use scratch space to
* copy the deletee pointer, then the latter references are via that
* scratch pointer rather than through the repointed (users) symbol.
*/
#define HASH_DELETE(hh,head,delptr) \
do { \
unsigned _hd_bkt; \
struct UT_hash_handle *_hd_hh_del; \
if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \
uthash_free((head)->hh.tbl->buckets, \
(head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
HASH_BLOOM_FREE((head)->hh.tbl); \
uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \
head = NULL; \
} else { \
_hd_hh_del = &((delptr)->hh); \
if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \
(head)->hh.tbl->tail = \
(UT_hash_handle*)((char*)((delptr)->hh.prev) + \
(head)->hh.tbl->hho); \
} \
if ((delptr)->hh.prev) { \
((UT_hash_handle*)((char*)((delptr)->hh.prev) + \
(head)->hh.tbl->hho))->next = (delptr)->hh.next; \
} else { \
DECLTYPE_ASSIGN(head,(delptr)->hh.next); \
} \
if (_hd_hh_del->next) { \
((UT_hash_handle*)((char*)_hd_hh_del->next + \
(head)->hh.tbl->hho))->prev = \
_hd_hh_del->prev; \
} \
HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \
HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \
(head)->hh.tbl->num_items--; \
} \
HASH_FSCK(hh,head); \
} while (0)
/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */
#define HASH_FIND_STR(head,findstr,out) \
HASH_FIND(hh,head,findstr,strlen(findstr),out)
#define HASH_ADD_STR(head,strfield,add) \
HASH_ADD(hh,head,strfield,strlen(add->strfield),add)
#define HASH_FIND_INT(head,findint,out) \
HASH_FIND(hh,head,findint,sizeof(int),out)
#define HASH_ADD_INT(head,intfield,add) \
HASH_ADD(hh,head,intfield,sizeof(int),add)
#define HASH_FIND_PTR(head,findptr,out) \
HASH_FIND(hh,head,findptr,sizeof(void *),out)
#define HASH_ADD_PTR(head,ptrfield,add) \
HASH_ADD(hh,head,ptrfield,sizeof(void *),add)
#define HASH_DEL(head,delptr) \
HASH_DELETE(hh,head,delptr)
/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined.
* This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.
*/
#ifdef HASH_DEBUG
#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0)
#define HASH_FSCK(hh,head) \
do { \
unsigned _bkt_i; \
unsigned _count, _bkt_count; \
char *_prev; \
struct UT_hash_handle *_thh; \
if (head) { \
_count = 0; \
for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \
_bkt_count = 0; \
_thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \
_prev = NULL; \
while (_thh) { \
if (_prev != (char*)(_thh->hh_prev)) { \
HASH_OOPS("invalid hh_prev %p, actual %p\n", \
_thh->hh_prev, _prev ); \
} \
_bkt_count++; \
_prev = (char*)(_thh); \
_thh = _thh->hh_next; \
} \
_count += _bkt_count; \
if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \
HASH_OOPS("invalid bucket count %d, actual %d\n", \
(head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \
} \
} \
if (_count != (head)->hh.tbl->num_items) { \
HASH_OOPS("invalid hh item count %d, actual %d\n", \
(head)->hh.tbl->num_items, _count ); \
} \
/* traverse hh in app order; check next/prev integrity, count */ \
_count = 0; \
_prev = NULL; \
_thh = &(head)->hh; \
while (_thh) { \
_count++; \
if (_prev !=(char*)(_thh->prev)) { \
HASH_OOPS("invalid prev %p, actual %p\n", \
_thh->prev, _prev ); \
} \
_prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \
_thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \
(head)->hh.tbl->hho) : NULL ); \
} \
if (_count != (head)->hh.tbl->num_items) { \
HASH_OOPS("invalid app item count %d, actual %d\n", \
(head)->hh.tbl->num_items, _count ); \
} \
} \
} while (0)
#else
#define HASH_FSCK(hh,head)
#endif
/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to
* the descriptor to which this macro is defined for tuning the hash function.
* The app can #include <unistd.h> to get the prototype for write(2). */
#ifdef HASH_EMIT_KEYS
#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \
do { \
unsigned _klen = fieldlen; \
write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \
write(HASH_EMIT_KEYS, keyptr, fieldlen); \
} while (0)
#else
#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)
#endif
/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
#ifdef HASH_FUNCTION
#define HASH_FCN HASH_FUNCTION
#else
#define HASH_FCN HASH_JEN
#endif
/* The Bernstein hash function, used in Perl prior to v5.6 */
#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \
do { \
unsigned _hb_keylen=keylen; \
char *_hb_key=(char*)(key); \
(hashv) = 0; \
while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \
bkt = (hashv) & (num_bkts-1); \
} while (0)
/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \
do { \
unsigned _sx_i; \
char *_hs_key=(char*)(key); \
hashv = 0; \
for(_sx_i=0; _sx_i < keylen; _sx_i++) \
hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \
bkt = hashv & (num_bkts-1); \
} while (0)
#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \
do { \
unsigned _fn_i; \
char *_hf_key=(char*)(key); \
hashv = 2166136261UL; \
for(_fn_i=0; _fn_i < keylen; _fn_i++) \
hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \
bkt = hashv & (num_bkts-1); \
} while(0);
#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \
do { \
unsigned _ho_i; \
char *_ho_key=(char*)(key); \
hashv = 0; \
for(_ho_i=0; _ho_i < keylen; _ho_i++) { \
hashv += _ho_key[_ho_i]; \
hashv += (hashv << 10); \
hashv ^= (hashv >> 6); \
} \
hashv += (hashv << 3); \
hashv ^= (hashv >> 11); \
hashv += (hashv << 15); \
bkt = hashv & (num_bkts-1); \
} while(0)
#define HASH_JEN_MIX(a,b,c) \
do { \
a -= b; a -= c; a ^= ( c >> 13 ); \
b -= c; b -= a; b ^= ( a << 8 ); \
c -= a; c -= b; c ^= ( b >> 13 ); \
a -= b; a -= c; a ^= ( c >> 12 ); \
b -= c; b -= a; b ^= ( a << 16 ); \
c -= a; c -= b; c ^= ( b >> 5 ); \
a -= b; a -= c; a ^= ( c >> 3 ); \
b -= c; b -= a; b ^= ( a << 10 ); \
c -= a; c -= b; c ^= ( b >> 15 ); \
} while (0)
#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \
do { \
unsigned _hj_i,_hj_j,_hj_k; \
char *_hj_key=(char*)(key); \
hashv = 0xfeedbeef; \
_hj_i = _hj_j = 0x9e3779b9; \
_hj_k = keylen; \
while (_hj_k >= 12) { \
_hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \
+ ( (unsigned)_hj_key[2] << 16 ) \
+ ( (unsigned)_hj_key[3] << 24 ) ); \
_hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \
+ ( (unsigned)_hj_key[6] << 16 ) \
+ ( (unsigned)_hj_key[7] << 24 ) ); \
hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \
+ ( (unsigned)_hj_key[10] << 16 ) \
+ ( (unsigned)_hj_key[11] << 24 ) ); \
\
HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
\
_hj_key += 12; \
_hj_k -= 12; \
} \
hashv += keylen; \
switch ( _hj_k ) { \
case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \
case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \
case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \
case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \
case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \
case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \
case 5: _hj_j += _hj_key[4]; \
case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \
case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \
case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \
case 1: _hj_i += _hj_key[0]; \
} \
HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
bkt = hashv & (num_bkts-1); \
} while(0)
/* The Paul Hsieh hash function */
#undef get16bits
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
#define get16bits(d) (*((const uint16_t *) (d)))
#endif
#if !defined (get16bits)
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \
+(uint32_t)(((const uint8_t *)(d))[0]) )
#endif
#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \
do { \
char *_sfh_key=(char*)(key); \
uint32_t _sfh_tmp, _sfh_len = keylen; \
\
int _sfh_rem = _sfh_len & 3; \
_sfh_len >>= 2; \
hashv = 0xcafebabe; \
\
/* Main loop */ \
for (;_sfh_len > 0; _sfh_len--) { \
hashv += get16bits (_sfh_key); \
_sfh_tmp = (get16bits (_sfh_key+2) << 11) ^ hashv; \
hashv = (hashv << 16) ^ _sfh_tmp; \
_sfh_key += 2*sizeof (uint16_t); \
hashv += hashv >> 11; \
} \
\
/* Handle end cases */ \
switch (_sfh_rem) { \
case 3: hashv += get16bits (_sfh_key); \
hashv ^= hashv << 16; \
hashv ^= _sfh_key[sizeof (uint16_t)] << 18; \
hashv += hashv >> 11; \
break; \
case 2: hashv += get16bits (_sfh_key); \
hashv ^= hashv << 11; \
hashv += hashv >> 17; \
break; \
case 1: hashv += *_sfh_key; \
hashv ^= hashv << 10; \
hashv += hashv >> 1; \
} \
\
/* Force "avalanching" of final 127 bits */ \
hashv ^= hashv << 3; \
hashv += hashv >> 5; \
hashv ^= hashv << 4; \
hashv += hashv >> 17; \
hashv ^= hashv << 25; \
hashv += hashv >> 6; \
bkt = hashv & (num_bkts-1); \
} while(0);
#ifdef HASH_USING_NO_STRICT_ALIASING
/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads.
* For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.
* MurmurHash uses the faster approach only on CPU's where we know it's safe.
*
* Note the preprocessor built-in defines can be emitted using:
*
* gcc -m64 -dM -E - < /dev/null (on gcc)
* cc -## a.c (where a.c is a simple test file) (Sun Studio)
*/
#if (defined(__i386__) || defined(__x86_64__))
#define MUR_GETBLOCK(p,i) p[i]
#else /* non intel */
#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0)
#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1)
#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2)
#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3)
#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL))
#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__))
#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24))
#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16))
#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8))
#else /* assume little endian non-intel */
#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24))
#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16))
#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8))
#endif
#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \
(MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \
(MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \
MUR_ONE_THREE(p))))
#endif
#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
#define MUR_FMIX(_h) \
do { \
_h ^= _h >> 16; \
_h *= 0x85ebca6b; \
_h ^= _h >> 13; \
_h *= 0xc2b2ae35l; \
_h ^= _h >> 16; \
} while(0)
#define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \
do { \
const uint8_t *_mur_data = (const uint8_t*)(key); \
const int _mur_nblocks = (keylen) / 4; \
uint32_t _mur_h1 = 0xf88D5353; \
uint32_t _mur_c1 = 0xcc9e2d51; \
uint32_t _mur_c2 = 0x1b873593; \
const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \
int _mur_i; \
for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \
uint32_t _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \
_mur_k1 *= _mur_c1; \
_mur_k1 = MUR_ROTL32(_mur_k1,15); \
_mur_k1 *= _mur_c2; \
\
_mur_h1 ^= _mur_k1; \
_mur_h1 = MUR_ROTL32(_mur_h1,13); \
_mur_h1 = _mur_h1*5+0xe6546b64; \
} \
const uint8_t *_mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \
uint32_t _mur_k1=0; \
switch((keylen) & 3) { \
case 3: _mur_k1 ^= _mur_tail[2] << 16; \
case 2: _mur_k1 ^= _mur_tail[1] << 8; \
case 1: _mur_k1 ^= _mur_tail[0]; \
_mur_k1 *= _mur_c1; \
_mur_k1 = MUR_ROTL32(_mur_k1,15); \
_mur_k1 *= _mur_c2; \
_mur_h1 ^= _mur_k1; \
} \
_mur_h1 ^= (keylen); \
MUR_FMIX(_mur_h1); \
hashv = _mur_h1; \
bkt = hashv & (num_bkts-1); \
} while(0)
#endif /* HASH_USING_NO_STRICT_ALIASING */
/* key comparison function; return 0 if keys equal */
#define HASH_KEYCMP(a,b,len) memcmp(a,b,len)
/* iterate over items in a known bucket to find desired item */
#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \
do { \
if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \
else out=NULL; \
while (out) { \
if (out->hh.keylen == keylen_in) { \
if ((HASH_KEYCMP(out->hh.key,keyptr,keylen_in)) == 0) break; \
} \
if (out->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,out->hh.hh_next)); \
else out = NULL; \
} \
} while(0)
/* add an item to a bucket */
#define HASH_ADD_TO_BKT(head,addhh) \
do { \
head.count++; \
(addhh)->hh_next = head.hh_head; \
(addhh)->hh_prev = NULL; \
if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \
(head).hh_head=addhh; \
if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \
&& (addhh)->tbl->noexpand != 1) { \
HASH_EXPAND_BUCKETS((addhh)->tbl); \
} \
} while(0)
/* remove an item from a given bucket */
#define HASH_DEL_IN_BKT(hh,head,hh_del) \
(head).count--; \
if ((head).hh_head == hh_del) { \
(head).hh_head = hh_del->hh_next; \
} \
if (hh_del->hh_prev) { \
hh_del->hh_prev->hh_next = hh_del->hh_next; \
} \
if (hh_del->hh_next) { \
hh_del->hh_next->hh_prev = hh_del->hh_prev; \
}
/* Bucket expansion has the effect of doubling the number of buckets
* and redistributing the items into the new buckets. Ideally the
* items will distribute more or less evenly into the new buckets
* (the extent to which this is true is a measure of the quality of
* the hash function as it applies to the key domain).
*
* With the items distributed into more buckets, the chain length
* (item count) in each bucket is reduced. Thus by expanding buckets
* the hash keeps a bound on the chain length. This bounded chain
* length is the essence of how a hash provides constant time lookup.
*
* The calculation of tbl->ideal_chain_maxlen below deserves some
* explanation. First, keep in mind that we're calculating the ideal
* maximum chain length based on the *new* (doubled) bucket count.
* In fractions this is just n/b (n=number of items,b=new num buckets).
* Since the ideal chain length is an integer, we want to calculate
* ceil(n/b). We don't depend on floating point arithmetic in this
* hash, so to calculate ceil(n/b) with integers we could write
*
* ceil(n/b) = (n/b) + ((n%b)?1:0)
*
* and in fact a previous version of this hash did just that.
* But now we have improved things a bit by recognizing that b is
* always a power of two. We keep its base 2 log handy (call it lb),
* so now we can write this with a bit shift and logical AND:
*
* ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0)
*
*/
#define HASH_EXPAND_BUCKETS(tbl) \
do { \
unsigned _he_bkt; \
unsigned _he_bkt_i; \
struct UT_hash_handle *_he_thh, *_he_hh_nxt; \
UT_hash_bucket *_he_new_buckets, *_he_newbkt; \
_he_new_buckets = (UT_hash_bucket*)uthash_malloc( \
2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \
memset(_he_new_buckets, 0, \
2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
tbl->ideal_chain_maxlen = \
(tbl->num_items >> (tbl->log2_num_buckets+1)) + \
((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \
tbl->nonideal_items = 0; \
for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \
{ \
_he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \
while (_he_thh) { \
_he_hh_nxt = _he_thh->hh_next; \
HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \
_he_newbkt = &(_he_new_buckets[ _he_bkt ]); \
if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \
tbl->nonideal_items++; \
_he_newbkt->expand_mult = _he_newbkt->count / \
tbl->ideal_chain_maxlen; \
} \
_he_thh->hh_prev = NULL; \
_he_thh->hh_next = _he_newbkt->hh_head; \
if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \
_he_thh; \
_he_newbkt->hh_head = _he_thh; \
_he_thh = _he_hh_nxt; \
} \
} \
uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
tbl->num_buckets *= 2; \
tbl->log2_num_buckets++; \
tbl->buckets = _he_new_buckets; \
tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \
(tbl->ineff_expands+1) : 0; \
if (tbl->ineff_expands > 1) { \
tbl->noexpand=1; \
uthash_noexpand_fyi(tbl); \
} \
uthash_expand_fyi(tbl); \
} while(0)
/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */
/* Note that HASH_SORT assumes the hash handle name to be hh.
* HASH_SRT was added to allow the hash handle name to be passed in. */
#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn)
#define HASH_SRT(hh,head,cmpfcn) \
do { \
unsigned _hs_i; \
unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \
struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \
if (head) { \
_hs_insize = 1; \
_hs_looping = 1; \
_hs_list = &((head)->hh); \
while (_hs_looping) { \
_hs_p = _hs_list; \
_hs_list = NULL; \
_hs_tail = NULL; \
_hs_nmerges = 0; \
while (_hs_p) { \
_hs_nmerges++; \
_hs_q = _hs_p; \
_hs_psize = 0; \
for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \
_hs_psize++; \
_hs_q = (UT_hash_handle*)((_hs_q->next) ? \
((void*)((char*)(_hs_q->next) + \
(head)->hh.tbl->hho)) : NULL); \
if (! (_hs_q) ) break; \
} \
_hs_qsize = _hs_insize; \
while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \
if (_hs_psize == 0) { \
_hs_e = _hs_q; \
_hs_q = (UT_hash_handle*)((_hs_q->next) ? \
((void*)((char*)(_hs_q->next) + \
(head)->hh.tbl->hho)) : NULL); \
_hs_qsize--; \
} else if ( (_hs_qsize == 0) || !(_hs_q) ) { \
_hs_e = _hs_p; \
_hs_p = (UT_hash_handle*)((_hs_p->next) ? \
((void*)((char*)(_hs_p->next) + \
(head)->hh.tbl->hho)) : NULL); \
_hs_psize--; \
} else if (( \
cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \
DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \
) <= 0) { \
_hs_e = _hs_p; \
_hs_p = (UT_hash_handle*)((_hs_p->next) ? \
((void*)((char*)(_hs_p->next) + \
(head)->hh.tbl->hho)) : NULL); \
_hs_psize--; \
} else { \
_hs_e = _hs_q; \
_hs_q = (UT_hash_handle*)((_hs_q->next) ? \
((void*)((char*)(_hs_q->next) + \
(head)->hh.tbl->hho)) : NULL); \
_hs_qsize--; \
} \
if ( _hs_tail ) { \
_hs_tail->next = ((_hs_e) ? \
ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \
} else { \
_hs_list = _hs_e; \
} \
_hs_e->prev = ((_hs_tail) ? \
ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \
_hs_tail = _hs_e; \
} \
_hs_p = _hs_q; \
} \
_hs_tail->next = NULL; \
if ( _hs_nmerges <= 1 ) { \
_hs_looping=0; \
(head)->hh.tbl->tail = _hs_tail; \
DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \
} \
_hs_insize *= 2; \
} \
HASH_FSCK(hh,head); \
} \
} while (0)
/* This function selects items from one hash into another hash.
* The end result is that the selected items have dual presence
* in both hashes. There is no copy of the items made; rather
* they are added into the new hash through a secondary hash
* hash handle that must be present in the structure. */
#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \
do { \
unsigned _src_bkt, _dst_bkt; \
void *_last_elt=NULL, *_elt; \
UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \
ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \
if (src) { \
for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \
for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \
_src_hh; \
_src_hh = _src_hh->hh_next) { \
_elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \
if (cond(_elt)) { \
_dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \
_dst_hh->key = _src_hh->key; \
_dst_hh->keylen = _src_hh->keylen; \
_dst_hh->hashv = _src_hh->hashv; \
_dst_hh->prev = _last_elt; \
_dst_hh->next = NULL; \
if (_last_elt_hh) { _last_elt_hh->next = _elt; } \
if (!dst) { \
DECLTYPE_ASSIGN(dst,_elt); \
HASH_MAKE_TABLE(hh_dst,dst); \
} else { \
_dst_hh->tbl = (dst)->hh_dst.tbl; \
} \
HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \
HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \
(dst)->hh_dst.tbl->num_items++; \
_last_elt = _elt; \
_last_elt_hh = _dst_hh; \
} \
} \
} \
} \
HASH_FSCK(hh_dst,dst); \
} while (0)
#define HASH_CLEAR(hh,head) \
do { \
if (head) { \
uthash_free((head)->hh.tbl->buckets, \
(head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \
uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \
(head)=NULL; \
} \
} while(0)
#ifdef NO_DECLTYPE
#define HASH_ITER(hh,head,el,tmp) \
for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \
el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL))
#else
#define HASH_ITER(hh,head,el,tmp) \
for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \
el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL))
#endif
/* obtain a count of items in the hash */
#define HASH_COUNT(head) HASH_CNT(hh,head)
#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0)
typedef struct UT_hash_bucket {
struct UT_hash_handle *hh_head;
unsigned count;
/* expand_mult is normally set to 0. In this situation, the max chain length
* threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If
* the bucket's chain exceeds this length, bucket expansion is triggered).
* However, setting expand_mult to a non-zero value delays bucket expansion
* (that would be triggered by additions to this particular bucket)
* until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH.
* (The multiplier is simply expand_mult+1). The whole idea of this
* multiplier is to reduce bucket expansions, since they are expensive, in
* situations where we know that a particular bucket tends to be overused.
* It is better to let its chain length grow to a longer yet-still-bounded
* value, than to do an O(n) bucket expansion too often.
*/
unsigned expand_mult;
} UT_hash_bucket;
/* random signature used only to find hash tables in external analysis */
#define HASH_SIGNATURE 0xa0111fe1
#define HASH_BLOOM_SIGNATURE 0xb12220f2
typedef struct UT_hash_table {
UT_hash_bucket *buckets;
unsigned num_buckets, log2_num_buckets;
unsigned num_items;
struct UT_hash_handle *tail; /* tail hh in app order, for fast append */
ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */
/* in an ideal situation (all buckets used equally), no bucket would have
* more than ceil(#items/#buckets) items. that's the ideal chain length. */
unsigned ideal_chain_maxlen;
/* nonideal_items is the number of items in the hash whose chain position
* exceeds the ideal chain maxlen. these items pay the penalty for an uneven
* hash distribution; reaching them in a chain traversal takes >ideal steps */
unsigned nonideal_items;
/* ineffective expands occur when a bucket doubling was performed, but
* afterward, more than half the items in the hash had nonideal chain
* positions. If this happens on two consecutive expansions we inhibit any
* further expansion, as it's not helping; this happens when the hash
* function isn't a good fit for the key domain. When expansion is inhibited
* the hash will still work, albeit no longer in constant time. */
unsigned ineff_expands, noexpand;
uint32_t signature; /* used only to find hash tables in external analysis */
#ifdef HASH_BLOOM
uint32_t bloom_sig; /* used only to test bloom exists in external analysis */
uint8_t *bloom_bv;
char bloom_nbits;
#endif
} UT_hash_table;
typedef struct UT_hash_handle {
struct UT_hash_table *tbl;
void *prev; /* prev element in app order */
void *next; /* next element in app order */
struct UT_hash_handle *hh_prev; /* previous hh in bucket order */
struct UT_hash_handle *hh_next; /* next hh in bucket order */
void *key; /* ptr to enclosing struct's key */
unsigned keylen; /* enclosing struct's key len */
unsigned hashv; /* result of hash-fcn(key) */
} UT_hash_handle;
#endif /* UTHASH_H */
+24
Переглянути файл
@@ -0,0 +1,24 @@
/*
************************************************************************************************************************
*
* Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
*
***********************************************************************************************************************/
#ifndef _AR_H_
#define _AR_H_ 1
#define ARMAG "!<arch>\n"
#define SARMAG 8
#define ARFMAG "`\n"
struct ar_hdr {
char ar_name[16];
char ar_date[12];
char ar_uid[6], ar_gid[6];
char ar_mode[8];
char ar_size[10];
char ar_fmag[2];
};
#endif
+57
Переглянути файл
@@ -0,0 +1,57 @@
/*
************************************************************************************************************************
*
* Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
*
***********************************************************************************************************************/
#ifndef _COMPAT_H_
#define _COMPAT_H_ 1
#pragma warning(disable:4244 4267)
#include <sys/cdefs.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include "sys/mman.h"
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
typedef uint8_t u_int8_t;
typedef uint16_t u_int16_t;
typedef uint32_t u_int32_t;
typedef uint64_t u_int64_t;
#ifndef _WIN64
typedef __int32 ssize_t;
#else // _WIN64
typedef __int64 ssize_t;
#endif // _WIN64
typedef long uid_t;
typedef long gid_t;
typedef long mode_t;
typedef long off_t;
#if _MSC_VER < 1900
#ifndef snprintf
# define snprintf sprintf_s
#endif
#ifndef fstat
# define fstat(A, B) _fstat((A), (struct _stat*)(B))
#endif
#endif
#ifndef S_ISCHR
#define S_ISCHR(A) (((A) & S_IFMT) == S_IFCHR)
#endif
#ifndef S_ISREG
#define S_ISREG(A) (((A) & S_IFMT) == S_IFREG)
#endif
#endif
@@ -0,0 +1,19 @@
/*
************************************************************************************************************************
*
* Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
*
***********************************************************************************************************************/
#ifndef _SYS_CDEFS_H_
#define _SYS_CDEFS_H_ 1
#ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
#else
# define __BEGIN_DECLS
# define __END_DECLS
#endif
#endif
+163
Переглянути файл
@@ -0,0 +1,163 @@
/*-
* Copyright (c) 1996-1998 John D. Polstra.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $
*/
#ifndef _SYS_ELF32_H_
#define _SYS_ELF32_H_ 1
#include "elf_common.h"
/*
* ELF definitions common to all 32-bit architectures.
*/
typedef uint32_t Elf32_Addr;
typedef uint16_t Elf32_Half;
typedef uint32_t Elf32_Off;
typedef int32_t Elf32_Sword;
typedef uint32_t Elf32_Word;
typedef Elf32_Word Elf32_Hashelt;
/* Non-standard class-dependent datatype used for abstraction. */
typedef Elf32_Word Elf32_Size;
typedef Elf32_Sword Elf32_Ssize;
/*
* ELF header.
*/
typedef struct {
unsigned char e_ident[EI_NIDENT]; /* File identification. */
Elf32_Half e_type; /* File type. */
Elf32_Half e_machine; /* Machine architecture. */
Elf32_Word e_version; /* ELF format version. */
Elf32_Addr e_entry; /* Entry point. */
Elf32_Off e_phoff; /* Program header file offset. */
Elf32_Off e_shoff; /* Section header file offset. */
Elf32_Word e_flags; /* Architecture-specific flags. */
Elf32_Half e_ehsize; /* Size of ELF header in bytes. */
Elf32_Half e_phentsize; /* Size of program header entry. */
Elf32_Half e_phnum; /* Number of program header entries. */
Elf32_Half e_shentsize; /* Size of section header entry. */
Elf32_Half e_shnum; /* Number of section header entries. */
Elf32_Half e_shstrndx; /* Section name strings section. */
} Elf32_Ehdr;
/*
* Section header.
*/
typedef struct {
Elf32_Word sh_name; /* Section name (index into the
section header string table). */
Elf32_Word sh_type; /* Section type. */
Elf32_Word sh_flags; /* Section flags. */
Elf32_Addr sh_addr; /* Address in memory image. */
Elf32_Off sh_offset; /* Offset in file. */
Elf32_Word sh_size; /* Size in bytes. */
Elf32_Word sh_link; /* Index of a related section. */
Elf32_Word sh_info; /* Depends on section type. */
Elf32_Word sh_addralign; /* Alignment in bytes. */
Elf32_Word sh_entsize; /* Size of each entry in section. */
} Elf32_Shdr;
/*
* Program header.
*/
typedef struct {
Elf32_Word p_type; /* Entry type. */
Elf32_Off p_offset; /* File offset of contents. */
Elf32_Addr p_vaddr; /* Virtual address in memory image. */
Elf32_Addr p_paddr; /* Physical address (not used). */
Elf32_Word p_filesz; /* Size of contents in file. */
Elf32_Word p_memsz; /* Size of contents in memory. */
Elf32_Word p_flags; /* Access permission flags. */
Elf32_Word p_align; /* Alignment in memory and file. */
} Elf32_Phdr;
/*
* Dynamic structure. The ".dynamic" section contains an array of them.
*/
typedef struct {
Elf32_Sword d_tag; /* Entry type. */
union {
Elf32_Word d_val; /* Integer value. */
Elf32_Addr d_ptr; /* Address value. */
} d_un;
} Elf32_Dyn;
/*
* Relocation entries.
*/
/* Relocations that don't need an addend field. */
typedef struct {
Elf32_Addr r_offset; /* Location to be relocated. */
Elf32_Word r_info; /* Relocation type and symbol index. */
} Elf32_Rel;
/* Relocations that need an addend field. */
typedef struct {
Elf32_Addr r_offset; /* Location to be relocated. */
Elf32_Word r_info; /* Relocation type and symbol index. */
Elf32_Sword r_addend; /* Addend. */
} Elf32_Rela;
/* Macros for accessing the fields of r_info. */
#define ELF32_R_SYM(info) ((info) >> 8)
#define ELF32_R_TYPE(info) ((unsigned char)(info))
/* Macro for constructing r_info from field values. */
#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type))
/*
* Symbol table entries.
*/
typedef struct {
Elf32_Word st_name; /* String table index of name. */
Elf32_Addr st_value; /* Symbol value. */
Elf32_Word st_size; /* Size of associated object. */
unsigned char st_info; /* Type and binding information. */
unsigned char st_other; /* Reserved (not used). */
Elf32_Half st_shndx; /* Section index of symbol. */
} Elf32_Sym;
/* Macros for accessing the fields of st_info. */
#define ELF32_ST_BIND(info) ((info) >> 4)
#define ELF32_ST_TYPE(info) ((info) & 0xf)
/* Macro for constructing st_info from field values. */
#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
/* Macro for accessing the fields of st_other. */
#define ELF32_ST_VISIBILITY(oth) ((oth) & 0x3)
#endif /* !_SYS_ELF32_H_ */
+176
Переглянути файл
@@ -0,0 +1,176 @@
/*-
* Copyright (c) 1996-1998 John D. Polstra.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $
*/
#ifndef _SYS_ELF64_H_
#define _SYS_ELF64_H_ 1
#include "elf_common.h"
/*
* ELF definitions common to all 64-bit architectures.
*/
typedef uint64_t Elf64_Addr;
typedef uint16_t Elf64_Half;
typedef uint64_t Elf64_Off;
typedef int32_t Elf64_Sword;
typedef int64_t Elf64_Sxword;
typedef uint32_t Elf64_Word;
typedef uint64_t Elf64_Xword;
/*
* Types of dynamic symbol hash table bucket and chain elements.
*
* This is inconsistent among 64 bit architectures, so a machine dependent
* typedef is required.
*/
#ifdef __alpha__
typedef Elf64_Off Elf64_Hashelt;
#else
typedef Elf64_Word Elf64_Hashelt;
#endif
/* Non-standard class-dependent datatype used for abstraction. */
typedef Elf64_Xword Elf64_Size;
typedef Elf64_Sxword Elf64_Ssize;
/*
* ELF header.
*/
typedef struct {
unsigned char e_ident[EI_NIDENT]; /* File identification. */
Elf64_Half e_type; /* File type. */
Elf64_Half e_machine; /* Machine architecture. */
Elf64_Word e_version; /* ELF format version. */
Elf64_Addr e_entry; /* Entry point. */
Elf64_Off e_phoff; /* Program header file offset. */
Elf64_Off e_shoff; /* Section header file offset. */
Elf64_Word e_flags; /* Architecture-specific flags. */
Elf64_Half e_ehsize; /* Size of ELF header in bytes. */
Elf64_Half e_phentsize; /* Size of program header entry. */
Elf64_Half e_phnum; /* Number of program header entries. */
Elf64_Half e_shentsize; /* Size of section header entry. */
Elf64_Half e_shnum; /* Number of section header entries. */
Elf64_Half e_shstrndx; /* Section name strings section. */
} Elf64_Ehdr;
/*
* Section header.
*/
typedef struct {
Elf64_Word sh_name; /* Section name (index into the
section header string table). */
Elf64_Word sh_type; /* Section type. */
Elf64_Xword sh_flags; /* Section flags. */
Elf64_Addr sh_addr; /* Address in memory image. */
Elf64_Off sh_offset; /* Offset in file. */
Elf64_Xword sh_size; /* Size in bytes. */
Elf64_Word sh_link; /* Index of a related section. */
Elf64_Word sh_info; /* Depends on section type. */
Elf64_Xword sh_addralign; /* Alignment in bytes. */
Elf64_Xword sh_entsize; /* Size of each entry in section. */
} Elf64_Shdr;
/*
* Program header.
*/
typedef struct {
Elf64_Word p_type; /* Entry type. */
Elf64_Word p_flags; /* Access permission flags. */
Elf64_Off p_offset; /* File offset of contents. */
Elf64_Addr p_vaddr; /* Virtual address in memory image. */
Elf64_Addr p_paddr; /* Physical address (not used). */
Elf64_Xword p_filesz; /* Size of contents in file. */
Elf64_Xword p_memsz; /* Size of contents in memory. */
Elf64_Xword p_align; /* Alignment in memory and file. */
} Elf64_Phdr;
/*
* Dynamic structure. The ".dynamic" section contains an array of them.
*/
typedef struct {
Elf64_Sxword d_tag; /* Entry type. */
union {
Elf64_Xword d_val; /* Integer value. */
Elf64_Addr d_ptr; /* Address value. */
} d_un;
} Elf64_Dyn;
/*
* Relocation entries.
*/
/* Relocations that don't need an addend field. */
typedef struct {
Elf64_Addr r_offset; /* Location to be relocated. */
Elf64_Xword r_info; /* Relocation type and symbol index. */
} Elf64_Rel;
/* Relocations that need an addend field. */
typedef struct {
Elf64_Addr r_offset; /* Location to be relocated. */
Elf64_Xword r_info; /* Relocation type and symbol index. */
Elf64_Sxword r_addend; /* Addend. */
} Elf64_Rela;
/* Macros for accessing the fields of r_info. */
#define ELF64_R_SYM(info) ((info) >> 32)
#define ELF64_R_TYPE(info) ((info) & 0xffffffffL)
/* Macro for constructing r_info from field values. */
#define ELF64_R_INFO(sym, type) (((sym) << 32) + ((type) & 0xffffffffL))
/*
* Symbol table entries.
*/
typedef struct {
Elf64_Word st_name; /* String table index of name. */
unsigned char st_info; /* Type and binding information. */
unsigned char st_other; /* Reserved (not used). */
Elf64_Half st_shndx; /* Section index of symbol. */
Elf64_Addr st_value; /* Symbol value. */
Elf64_Xword st_size; /* Size of associated object. */
} Elf64_Sym;
/* Macros for accessing the fields of st_info. */
#define ELF64_ST_BIND(info) ((info) >> 4)
#define ELF64_ST_TYPE(info) ((info) & 0xf)
/* Macro for constructing st_info from field values. */
#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
/* Macro for accessing the fields of st_other. */
#define ELF64_ST_VISIBILITY(oth) ((oth) & 0x3)
#endif /* !_SYS_ELF64_H_ */
@@ -0,0 +1,355 @@
/*-
* Copyright (c) 1998 John D. Polstra.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $
*/
#ifndef _SYS_ELF_COMMON_H_
#define _SYS_ELF_COMMON_H_ 1
/*
* ELF definitions that are independent of architecture or word size.
*/
/*
* Note header. The ".note" section contains an array of notes. Each
* begins with this header, aligned to a word boundary. Immediately
* following the note header is n_namesz bytes of name, padded to the
* next word boundary. Then comes n_descsz bytes of descriptor, again
* padded to a word boundary. The values of n_namesz and n_descsz do
* not include the padding.
*/
typedef struct {
u_int32_t n_namesz; /* Length of name. */
u_int32_t n_descsz; /* Length of descriptor. */
u_int32_t n_type; /* Type of this note. */
} Elf_Note;
/* Indexes into the e_ident array. Keep synced with
http://www.sco.com/developer/gabi/ch4.eheader.html */
#define EI_MAG0 0 /* Magic number, byte 0. */
#define EI_MAG1 1 /* Magic number, byte 1. */
#define EI_MAG2 2 /* Magic number, byte 2. */
#define EI_MAG3 3 /* Magic number, byte 3. */
#define EI_CLASS 4 /* Class of machine. */
#define EI_DATA 5 /* Data format. */
#define EI_VERSION 6 /* ELF format version. */
#define EI_OSABI 7 /* Operating system / ABI identification */
#define EI_ABIVERSION 8 /* ABI version */
#define OLD_EI_BRAND 8 /* Start of architecture identification. */
#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */
#define EI_NIDENT 16 /* Size of e_ident array. */
/* Values for the magic number bytes. */
#define ELFMAG0 0x7f
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
#define ELFMAG "\177ELF" /* magic string */
#define SELFMAG 4 /* magic string size */
/* Values for e_ident[EI_VERSION] and e_version. */
#define EV_NONE 0
#define EV_CURRENT 1
/* Values for e_ident[EI_CLASS]. */
#define ELFCLASSNONE 0 /* Unknown class. */
#define ELFCLASS32 1 /* 32-bit architecture. */
#define ELFCLASS64 2 /* 64-bit architecture. */
/* Values for e_ident[EI_DATA]. */
#define ELFDATANONE 0 /* Unknown data format. */
#define ELFDATA2LSB 1 /* 2's complement little-endian. */
#define ELFDATA2MSB 2 /* 2's complement big-endian. */
/* Values for e_ident[EI_OSABI]. */
#define ELFOSABI_NONE 0 /* UNIX System V ABI */
#define ELFOSABI_HPUX 1 /* HP-UX operating system */
#define ELFOSABI_NETBSD 2 /* NetBSD */
#define ELFOSABI_LINUX 3 /* GNU/Linux */
#define ELFOSABI_HURD 4 /* GNU/Hurd */
#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */
#define ELFOSABI_SOLARIS 6 /* Solaris */
#define ELFOSABI_AIX 7 /* AIX */
#define ELFOSABI_IRIX 8 /* IRIX */
#define ELFOSABI_FREEBSD 9 /* FreeBSD */
#define ELFOSABI_TRU64 10 /* TRU64 UNIX */
#define ELFOSABI_MODESTO 11 /* Novell Modesto */
#define ELFOSABI_OPENBSD 12 /* OpenBSD */
#define ELFOSABI_OPENVMS 13 /* Open VMS */
#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */
#define ELFOSABI_ARM 97 /* ARM */
#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
#define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */
#define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */
/* e_ident */
#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
(ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
(ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
(ehdr).e_ident[EI_MAG3] == ELFMAG3)
/* Values for e_type. */
#define ET_NONE 0 /* Unknown type. */
#define ET_REL 1 /* Relocatable. */
#define ET_EXEC 2 /* Executable. */
#define ET_DYN 3 /* Shared object. */
#define ET_CORE 4 /* Core file. */
#define ET_LOOS 0xfe00 /* First operating system specific. */
#define ET_HIOS 0xfeff /* Last operating system-specific. */
#define ET_LOPROC 0xff00 /* First processor-specific. */
#define ET_HIPROC 0xffff /* Last processor-specific. */
/* Values for e_machine. */
#define EM_NONE 0 /* Unknown machine. */
#define EM_M32 1 /* AT&T WE32100. */
#define EM_SPARC 2 /* Sun SPARC. */
#define EM_386 3 /* Intel i386. */
#define EM_68K 4 /* Motorola 68000. */
#define EM_88K 5 /* Motorola 88000. */
#define EM_860 7 /* Intel i860. */
#define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */
#define EM_S370 9 /* IBM System/370. */
#define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */
#define EM_PARISC 15 /* HP PA-RISC. */
#define EM_VPP500 17 /* Fujitsu VPP500. */
#define EM_SPARC32PLUS 18 /* SPARC v8plus. */
#define EM_960 19 /* Intel 80960. */
#define EM_PPC 20 /* PowerPC 32-bit. */
#define EM_PPC64 21 /* PowerPC 64-bit. */
#define EM_S390 22 /* IBM System/390. */
#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 /* ARM. */
#define EM_SH 42 /* Hitachi SH. */
#define EM_SPARCV9 43 /* SPARC v9 64-bit. */
#define EM_TRICORE 44 /* Siemens TriCore embedded processor. */
#define EM_ARC 45 /* Argonaut RISC Core. */
#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. */
#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. */
#define EM_PCP 55 /* Siemens PCP. */
#define EM_NCPU 56 /* Sony nCPU. */
#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 processor. */
#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */
/* Non-standard or deprecated. */
#define EM_486 6 /* Intel i486. */
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
#define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */
#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */
/* Special section indexes. */
#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */
#define SHN_LORESERVE 0xff00 /* First of reserved range. */
#define SHN_LOPROC 0xff00 /* First processor-specific. */
#define SHN_HIPROC 0xff1f /* Last processor-specific. */
#define SHN_LOOS 0xff20 /* First operating system-specific. */
#define SHN_HIOS 0xff3f /* Last operating system-specific. */
#define SHN_ABS 0xfff1 /* Absolute values. */
#define SHN_COMMON 0xfff2 /* Common data. */
#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */
#define SHN_HIRESERVE 0xffff /* Last of reserved range. */
/* sh_type */
#define SHT_NULL 0 /* inactive */
#define SHT_PROGBITS 1 /* program defined information */
#define SHT_SYMTAB 2 /* symbol table section */
#define SHT_STRTAB 3 /* string table section */
#define SHT_RELA 4 /* relocation section with addends */
#define SHT_HASH 5 /* symbol hash table section */
#define SHT_DYNAMIC 6 /* dynamic section */
#define SHT_NOTE 7 /* note section */
#define SHT_NOBITS 8 /* no space section */
#define SHT_REL 9 /* relocation section - no addends */
#define SHT_SHLIB 10 /* reserved - purpose unknown */
#define SHT_DYNSYM 11 /* dynamic symbol table section */
#define SHT_INIT_ARRAY 14 /* Initialization function pointers. */
#define SHT_FINI_ARRAY 15 /* Termination function pointers. */
#define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */
#define SHT_GROUP 17 /* Section group. */
#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */
#define SHT_LOOS 0x60000000 /* First of OS specific semantics */
#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
#define SHT_HIPROC 0x7fffffff /* specific section header types */
#define SHT_LOUSER 0x80000000 /* reserved range for application */
#define SHT_HIUSER 0xffffffff /* specific indexes */
/* Flags for sh_flags. */
#define SHF_WRITE 0x1 /* Section contains writable data. */
#define SHF_ALLOC 0x2 /* Section occupies memory. */
#define SHF_EXECINSTR 0x4 /* Section contains instructions. */
#define SHF_MERGE 0x10 /* Section may be merged. */
#define SHF_STRINGS 0x20 /* Section contains strings. */
#define SHF_INFO_LINK 0x40 /* sh_info holds section index. */
#define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */
#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */
#define SHF_GROUP 0x200 /* Member of section group. */
#define SHF_TLS 0x400 /* Section contains TLS data. */
#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */
#define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */
/* Values for p_type. */
#define PT_NULL 0 /* Unused entry. */
#define PT_LOAD 1 /* Loadable segment. */
#define PT_DYNAMIC 2 /* Dynamic linking information segment. */
#define PT_INTERP 3 /* Pathname of interpreter. */
#define PT_NOTE 4 /* Auxiliary information. */
#define PT_SHLIB 5 /* Reserved (not used). */
#define PT_PHDR 6 /* Location of program header itself. */
#define PT_TLS 7 /* Thread local storage segment */
#define PT_LOOS 0x60000000 /* First OS-specific. */
#define PT_HIOS 0x6fffffff /* Last OS-specific. */
#define PT_LOPROC 0x70000000 /* First processor-specific type. */
#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */
/* Values for p_flags. */
#define PF_X 0x1 /* Executable. */
#define PF_W 0x2 /* Writable. */
#define PF_R 0x4 /* Readable. */
#define PF_MASKOS 0x0ff00000 /* Operating system-specific. */
#define PF_MASKPROC 0xf0000000 /* Processor-specific. */
/* Values for d_tag. */
#define DT_NULL 0 /* Terminating entry. */
#define DT_NEEDED 1 /* String table offset of a needed shared
library. */
#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */
#define DT_PLTGOT 3 /* Processor-dependent address. */
#define DT_HASH 4 /* Address of symbol hash table. */
#define DT_STRTAB 5 /* Address of string table. */
#define DT_SYMTAB 6 /* Address of symbol table. */
#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */
#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */
#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */
#define DT_STRSZ 10 /* Size of string table. */
#define DT_SYMENT 11 /* Size of each symbol table entry. */
#define DT_INIT 12 /* Address of initialization function. */
#define DT_FINI 13 /* Address of finalization function. */
#define DT_SONAME 14 /* String table offset of shared object
name. */
#define DT_RPATH 15 /* String table offset of library path. [sup] */
#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */
#define DT_REL 17 /* Address of ElfNN_Rel relocations. */
#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */
#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */
#define DT_PLTREL 20 /* Type of relocation used for PLT. */
#define DT_DEBUG 21 /* Reserved (not used). */
#define DT_TEXTREL 22 /* Indicates there may be relocations in
non-writable segments. [sup] */
#define DT_JMPREL 23 /* Address of PLT relocations. */
#define DT_BIND_NOW 24 /* [sup] */
#define DT_INIT_ARRAY 25 /* Address of the array of pointers to
initialization functions */
#define DT_FINI_ARRAY 26 /* Address of the array of pointers to
termination functions */
#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of
initialization functions. */
#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of
terminationfunctions. */
#define DT_RUNPATH 29 /* String table offset of a null-terminated
library search path string. */
#define DT_FLAGS 30 /* Object specific flag values. */
#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING
and less than DT_LOOS follow the rules for
the interpretation of the d_un union
as follows: even == 'd_ptr', even == 'd_val'
or none */
#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to
pre-initialization functions. */
#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of
pre-initialization functions. */
#define DT_LOOS 0x6000000d /* First OS-specific */
#define DT_HIOS 0x6ffff000 /* Last OS-specific */
#define DT_LOPROC 0x70000000 /* First processor-specific type. */
#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */
/* Values for DT_FLAGS */
#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may
make reference to the $ORIGIN substitution
string */
#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */
#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in
non-writable segments. */
#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should
process all relocations for the object
containing this entry before transferring
control to the program. */
#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or
executable contains code using a static
thread-local storage scheme. */
/* Values for n_type. Used in core files. */
#define NT_PRSTATUS 1 /* Process status. */
#define NT_FPREGSET 2 /* Floating point registers. */
#define NT_PRPSINFO 3 /* Process state info. */
/* Symbol Binding - ELFNN_ST_BIND - st_info */
#define STB_LOCAL 0 /* Local symbol */
#define STB_GLOBAL 1 /* Global symbol */
#define STB_WEAK 2 /* like global - lower precedence */
#define STB_LOOS 10 /* Reserved range for operating system */
#define STB_HIOS 12 /* specific semantics. */
#define STB_LOPROC 13 /* reserved range for processor */
#define STB_HIPROC 15 /* specific semantics. */
/* Symbol type - ELFNN_ST_TYPE - st_info */
#define STT_NOTYPE 0 /* Unspecified type. */
#define STT_OBJECT 1 /* Data object. */
#define STT_FUNC 2 /* Function. */
#define STT_SECTION 3 /* Section. */
#define STT_FILE 4 /* Source file. */
#define STT_COMMON 5 /* Uninitialized common block. */
#define STT_TLS 6 /* TLS object. */
#define STT_LOOS 10 /* Reserved range for operating system */
#define STT_HIOS 12 /* specific semantics. */
#define STT_LOPROC 13 /* reserved range for processor */
#define STT_HIPROC 15 /* specific semantics. */
/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
#define STV_DEFAULT 0x0 /* Default visibility (see binding). */
#define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */
#define STV_HIDDEN 0x2 /* Not visible. */
#define STV_PROTECTED 0x3 /* Visible but not preemptible. */
/* Special symbol table indexes. */
#define STN_UNDEF 0 /* Undefined symbol index. */
#endif /* !_SYS_ELF_COMMON_H_ */
+15
Переглянути файл
@@ -0,0 +1,15 @@
/*
************************************************************************************************************************
*
* Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
*
***********************************************************************************************************************/
#ifndef _MMAN_H_
#define _MMAN_H_
#if defined(WIN32)
void *mmap(void*, size_t, int, int, int, unsigned);
int munmap(void*, size_t);
#endif
#endif // _MMAN_H_
@@ -0,0 +1,13 @@
/*
************************************************************************************************************************
*
* Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
*
***********************************************************************************************************************/
#ifndef _SYS_PARAM_H_
#define _SYS_PARAM_H_ 1
#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
#endif
+671
Переглянути файл
@@ -0,0 +1,671 @@
/* $NetBSD: queue.h,v 1.45.14.2 2009/06/05 16:23:34 snj Exp $ */
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)queue.h 8.5 (Berkeley) 8/20/94
*/
#ifndef _ELF_SYS_QUEUE_H_
#define _ELF_SYS_QUEUE_H_
/*
* This file defines five types of data structures: singly-linked lists,
* lists, simple queues, tail queues, and circular queues.
*
* A singly-linked list is headed by a single forward pointer. The
* elements are singly linked for minimum space and pointer manipulation
* overhead at the expense of O(n) removal for arbitrary elements. New
* elements can be added to the list after an existing element or at the
* head of the list. Elements being removed from the head of the list
* should use the explicit macro for this purpose for optimum
* efficiency. A singly-linked list may only be traversed in the forward
* direction. Singly-linked lists are ideal for applications with large
* datasets and few or no removals or for implementing a LIFO queue.
*
* A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction.
*
* A simple queue is headed by a pair of pointers, one the head of the
* list and the other to the tail of the list. The elements are singly
* linked to save space, so elements can only be removed from the
* head of the list. New elements can be added to the list after
* an existing element, at the head of the list, or at the end of the
* list. A simple queue may only be traversed in the forward direction.
*
* A tail queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or
* after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction.
*
* A circle queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or after
* an existing element, at the head of the list, or at the end of the list.
* A circle queue may be traversed in either direction, but has a more
* complex end of list detection.
*
* For details on the use of these macros, see the queue(3) manual page.
*/
/*
* List definitions.
*/
#define LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \
}
/*
* List functions.
*/
#if defined(_KERNEL) && defined(QUEUEDEBUG)
#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field) \
if ((head)->lh_first && \
(head)->lh_first->field.le_prev != &(head)->lh_first) \
panic("LIST_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
#define QUEUEDEBUG_LIST_OP(elm, field) \
if ((elm)->field.le_next && \
(elm)->field.le_next->field.le_prev != \
&(elm)->field.le_next) \
panic("LIST_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
if (*(elm)->field.le_prev != (elm)) \
panic("LIST_* back %p %s:%d", (elm), __FILE__, __LINE__);
#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field) \
(elm)->field.le_next = (void *)1L; \
(elm)->field.le_prev = (void *)1L;
#else
#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)
#define QUEUEDEBUG_LIST_OP(elm, field)
#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field)
#endif
#define LIST_INIT(head) do { \
(head)->lh_first = NULL; \
} while (/*CONSTCOND*/0)
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
QUEUEDEBUG_LIST_OP((listelm), field) \
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
(listelm)->field.le_next->field.le_prev = \
&(elm)->field.le_next; \
(listelm)->field.le_next = (elm); \
(elm)->field.le_prev = &(listelm)->field.le_next; \
} while (/*CONSTCOND*/0)
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
QUEUEDEBUG_LIST_OP((listelm), field) \
(elm)->field.le_prev = (listelm)->field.le_prev; \
(elm)->field.le_next = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &(elm)->field.le_next; \
} while (/*CONSTCOND*/0)
#define LIST_INSERT_HEAD(head, elm, field) do { \
QUEUEDEBUG_LIST_INSERT_HEAD((head), (elm), field) \
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
(head)->lh_first = (elm); \
(elm)->field.le_prev = &(head)->lh_first; \
} while (/*CONSTCOND*/0)
#define LIST_REMOVE(elm, field) do { \
QUEUEDEBUG_LIST_OP((elm), field) \
if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = (elm)->field.le_next; \
QUEUEDEBUG_LIST_POSTREMOVE((elm), field) \
} while (/*CONSTCOND*/0)
#define LIST_FOREACH(var, head, field) \
for ((var) = ((head)->lh_first); \
(var); \
(var) = ((var)->field.le_next))
/*
* List access methods.
*/
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
/*
* Singly-linked List definitions.
*/
#define ELF_SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first; /* first element */ \
}
#define ELF_SLIST_HEAD_INITIALIZER(head) \
{ NULL }
#define ELF_SLIST_ENTRY(type) \
struct { \
struct type *sle_next; /* next element */ \
}
/*
* Singly-linked List functions.
*/
#define ELF_SLIST_INIT(head) do { \
(head)->slh_first = NULL; \
} while (/*CONSTCOND*/0)
#define ELF_SLIST_INSERT_AFTER(slistelm, elm, field) do { \
(elm)->field.sle_next = (slistelm)->field.sle_next; \
(slistelm)->field.sle_next = (elm); \
} while (/*CONSTCOND*/0)
#define ELF_SLIST_INSERT_HEAD(head, elm, field) do { \
(elm)->field.sle_next = (head)->slh_first; \
(head)->slh_first = (elm); \
} while (/*CONSTCOND*/0)
#define ELF_SLIST_REMOVE_HEAD(head, field) do { \
(head)->slh_first = (head)->slh_first->field.sle_next; \
} while (/*CONSTCOND*/0)
#define ELF_SLIST_REMOVE(head, elm, type, field) do { \
if ((head)->slh_first == (elm)) { \
ELF_SLIST_REMOVE_HEAD((head), field); \
} \
else { \
struct type *curelm = (head)->slh_first; \
while(curelm->field.sle_next != (elm)) \
curelm = curelm->field.sle_next; \
curelm->field.sle_next = \
curelm->field.sle_next->field.sle_next; \
} \
} while (/*CONSTCOND*/0)
#define ELF_SLIST_FOREACH(var, head, field) \
for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
/*
* Singly-linked List access methods.
*/
#define ELF_SLIST_EMPTY(head) ((head)->slh_first == NULL)
#define ELF_SLIST_FIRST(head) ((head)->slh_first)
#define ELF_SLIST_NEXT(elm, field) ((elm)->field.sle_next)
/*
* Singly-linked Tail queue declarations.
*/
#define STAILQ_HEAD(name, type) \
struct name { \
struct type *stqh_first; /* first element */ \
struct type **stqh_last; /* addr of last next element */ \
}
#define STAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).stqh_first }
#define STAILQ_ENTRY(type) \
struct { \
struct type *stqe_next; /* next element */ \
}
/*
* Singly-linked Tail queue functions.
*/
#define STAILQ_INIT(head) do { \
(head)->stqh_first = NULL; \
(head)->stqh_last = &(head)->stqh_first; \
} while (/*CONSTCOND*/0)
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
(head)->stqh_last = &(elm)->field.stqe_next; \
(head)->stqh_first = (elm); \
} while (/*CONSTCOND*/0)
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.stqe_next = NULL; \
*(head)->stqh_last = (elm); \
(head)->stqh_last = &(elm)->field.stqe_next; \
} while (/*CONSTCOND*/0)
#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
(head)->stqh_last = &(elm)->field.stqe_next; \
(listelm)->field.stqe_next = (elm); \
} while (/*CONSTCOND*/0)
#define STAILQ_REMOVE_HEAD(head, field) do { \
if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
(head)->stqh_last = &(head)->stqh_first; \
} while (/*CONSTCOND*/0)
#define STAILQ_REMOVE(head, elm, type, field) do { \
if ((head)->stqh_first == (elm)) { \
STAILQ_REMOVE_HEAD((head), field); \
} else { \
struct type *curelm = (head)->stqh_first; \
while (curelm->field.stqe_next != (elm)) \
curelm = curelm->field.stqe_next; \
if ((curelm->field.stqe_next = \
curelm->field.stqe_next->field.stqe_next) == NULL) \
(head)->stqh_last = &(curelm)->field.stqe_next; \
} \
} while (/*CONSTCOND*/0)
#define STAILQ_FOREACH(var, head, field) \
for ((var) = ((head)->stqh_first); \
(var); \
(var) = ((var)->field.stqe_next))
/*
* Singly-linked Tail queue access methods.
*/
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
#define STAILQ_FIRST(head) ((head)->stqh_first)
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
/*
* Simple queue definitions.
*/
#define SIMPLEQ_HEAD(name, type) \
struct name { \
struct type *sqh_first; /* first element */ \
struct type **sqh_last; /* addr of last next element */ \
}
#define SIMPLEQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).sqh_first }
#define SIMPLEQ_ENTRY(type) \
struct { \
struct type *sqe_next; /* next element */ \
}
/*
* Simple queue functions.
*/
#define SIMPLEQ_INIT(head) do { \
(head)->sqh_first = NULL; \
(head)->sqh_last = &(head)->sqh_first; \
} while (/*CONSTCOND*/0)
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \
(head)->sqh_first = (elm); \
} while (/*CONSTCOND*/0)
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.sqe_next = NULL; \
*(head)->sqh_last = (elm); \
(head)->sqh_last = &(elm)->field.sqe_next; \
} while (/*CONSTCOND*/0)
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
(head)->sqh_last = &(elm)->field.sqe_next; \
(listelm)->field.sqe_next = (elm); \
} while (/*CONSTCOND*/0)
#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
(head)->sqh_last = &(head)->sqh_first; \
} while (/*CONSTCOND*/0)
#define SIMPLEQ_REMOVE(head, elm, type, field) do { \
if ((head)->sqh_first == (elm)) { \
SIMPLEQ_REMOVE_HEAD((head), field); \
} else { \
struct type *curelm = (head)->sqh_first; \
while (curelm->field.sqe_next != (elm)) \
curelm = curelm->field.sqe_next; \
if ((curelm->field.sqe_next = \
curelm->field.sqe_next->field.sqe_next) == NULL) \
(head)->sqh_last = &(curelm)->field.sqe_next; \
} \
} while (/*CONSTCOND*/0)
#define SIMPLEQ_FOREACH(var, head, field) \
for ((var) = ((head)->sqh_first); \
(var); \
(var) = ((var)->field.sqe_next))
/*
* Simple queue access methods.
*/
#define SIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL)
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
/*
* Tail queue definitions.
*/
#define _TAILQ_HEAD(name, type, qual) \
struct name { \
qual type *tqh_first; /* first element */ \
qual type *qual *tqh_last; /* addr of last next element */ \
}
#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,)
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
#define _TAILQ_ENTRY(type, qual) \
struct { \
qual type *tqe_next; /* next element */ \
qual type *qual *tqe_prev; /* address of previous next element */\
}
#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,)
/*
* Tail queue functions.
*/
#if defined(_KERNEL) && defined(QUEUEDEBUG)
#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field) \
if ((head)->tqh_first && \
(head)->tqh_first->field.tqe_prev != &(head)->tqh_first) \
panic("TAILQ_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field) \
if (*(head)->tqh_last != NULL) \
panic("TAILQ_INSERT_TAIL %p %s:%d", (head), __FILE__, __LINE__);
#define QUEUEDEBUG_TAILQ_OP(elm, field) \
if ((elm)->field.tqe_next && \
(elm)->field.tqe_next->field.tqe_prev != \
&(elm)->field.tqe_next) \
panic("TAILQ_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
if (*(elm)->field.tqe_prev != (elm)) \
panic("TAILQ_* back %p %s:%d", (elm), __FILE__, __LINE__);
#define QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field) \
if ((elm)->field.tqe_next == NULL && \
(head)->tqh_last != &(elm)->field.tqe_next) \
panic("TAILQ_PREREMOVE head %p elm %p %s:%d", \
(head), (elm), __FILE__, __LINE__);
#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field) \
(elm)->field.tqe_next = (void *)1L; \
(elm)->field.tqe_prev = (void *)1L;
#else
#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
#define QUEUEDEBUG_TAILQ_OP(elm, field)
#define QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field)
#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
#endif
#define TAILQ_INIT(head) do { \
(head)->tqh_first = NULL; \
(head)->tqh_last = &(head)->tqh_first; \
} while (/*CONSTCOND*/0)
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
QUEUEDEBUG_TAILQ_INSERT_HEAD((head), (elm), field) \
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
(head)->tqh_first->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(head)->tqh_first = (elm); \
(elm)->field.tqe_prev = &(head)->tqh_first; \
} while (/*CONSTCOND*/0)
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
QUEUEDEBUG_TAILQ_INSERT_TAIL((head), (elm), field) \
(elm)->field.tqe_next = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &(elm)->field.tqe_next; \
} while (/*CONSTCOND*/0)
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
QUEUEDEBUG_TAILQ_OP((listelm), field) \
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
(elm)->field.tqe_next->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(listelm)->field.tqe_next = (elm); \
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
} while (/*CONSTCOND*/0)
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
QUEUEDEBUG_TAILQ_OP((listelm), field) \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (/*CONSTCOND*/0)
#define TAILQ_REMOVE(head, elm, field) do { \
QUEUEDEBUG_TAILQ_PREREMOVE((head), (elm), field) \
QUEUEDEBUG_TAILQ_OP((elm), field) \
if (((elm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \
(elm)->field.tqe_prev; \
else \
(head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field); \
} while (/*CONSTCOND*/0)
#define TAILQ_FOREACH(var, head, field) \
for ((var) = ((head)->tqh_first); \
(var); \
(var) = ((var)->field.tqe_next))
#define TAILQ_FOREACH_SAFE(var, head, field, next) \
for ((var) = ((head)->tqh_first); \
(var) != NULL && ((next) = TAILQ_NEXT(var, field), 1); \
(var) = (next))
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
(var); \
(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
/*
* Tail queue access methods.
*/
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
#define TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
/*
* Circular queue definitions.
*/
#if defined(_KERNEL) && defined(QUEUEDEBUG)
#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field) \
if ((head)->cqh_first != (void *)(head) && \
(head)->cqh_first->field.cqe_prev != (void *)(head)) \
panic("CIRCLEQ head forw %p %s:%d", (head), \
__FILE__, __LINE__); \
if ((head)->cqh_last != (void *)(head) && \
(head)->cqh_last->field.cqe_next != (void *)(head)) \
panic("CIRCLEQ head back %p %s:%d", (head), \
__FILE__, __LINE__);
#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field) \
if ((elm)->field.cqe_next == (void *)(head)) { \
if ((head)->cqh_last != (elm)) \
panic("CIRCLEQ elm last %p %s:%d", (elm), \
__FILE__, __LINE__); \
} else { \
if ((elm)->field.cqe_next->field.cqe_prev != (elm)) \
panic("CIRCLEQ elm forw %p %s:%d", (elm), \
__FILE__, __LINE__); \
} \
if ((elm)->field.cqe_prev == (void *)(head)) { \
if ((head)->cqh_first != (elm)) \
panic("CIRCLEQ elm first %p %s:%d", (elm), \
__FILE__, __LINE__); \
} else { \
if ((elm)->field.cqe_prev->field.cqe_next != (elm)) \
panic("CIRCLEQ elm prev %p %s:%d", (elm), \
__FILE__, __LINE__); \
}
#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field) \
(elm)->field.cqe_next = (void *)1L; \
(elm)->field.cqe_prev = (void *)1L;
#else
#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field)
#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field)
#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field)
#endif
#define CIRCLEQ_HEAD(name, type) \
struct name { \
struct type *cqh_first; /* first element */ \
struct type *cqh_last; /* last element */ \
}
#define CIRCLEQ_HEAD_INITIALIZER(head) \
{ (void *)&head, (void *)&head }
#define CIRCLEQ_ENTRY(type) \
struct { \
struct type *cqe_next; /* next element */ \
struct type *cqe_prev; /* previous element */ \
}
/*
* Circular queue functions.
*/
#define CIRCLEQ_INIT(head) do { \
(head)->cqh_first = (void *)(head); \
(head)->cqh_last = (void *)(head); \
} while (/*CONSTCOND*/0)
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field) \
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
(elm)->field.cqe_prev = (listelm); \
if ((listelm)->field.cqe_next == (void *)(head)) \
(head)->cqh_last = (elm); \
else \
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
(listelm)->field.cqe_next = (elm); \
} while (/*CONSTCOND*/0)
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field) \
(elm)->field.cqe_next = (listelm); \
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
if ((listelm)->field.cqe_prev == (void *)(head)) \
(head)->cqh_first = (elm); \
else \
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
(listelm)->field.cqe_prev = (elm); \
} while (/*CONSTCOND*/0)
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
(elm)->field.cqe_next = (head)->cqh_first; \
(elm)->field.cqe_prev = (void *)(head); \
if ((head)->cqh_last == (void *)(head)) \
(head)->cqh_last = (elm); \
else \
(head)->cqh_first->field.cqe_prev = (elm); \
(head)->cqh_first = (elm); \
} while (/*CONSTCOND*/0)
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
(elm)->field.cqe_next = (void *)(head); \
(elm)->field.cqe_prev = (head)->cqh_last; \
if ((head)->cqh_first == (void *)(head)) \
(head)->cqh_first = (elm); \
else \
(head)->cqh_last->field.cqe_next = (elm); \
(head)->cqh_last = (elm); \
} while (/*CONSTCOND*/0)
#define CIRCLEQ_REMOVE(head, elm, field) do { \
QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
QUEUEDEBUG_CIRCLEQ_ELM((head), (elm), field) \
if ((elm)->field.cqe_next == (void *)(head)) \
(head)->cqh_last = (elm)->field.cqe_prev; \
else \
(elm)->field.cqe_next->field.cqe_prev = \
(elm)->field.cqe_prev; \
if ((elm)->field.cqe_prev == (void *)(head)) \
(head)->cqh_first = (elm)->field.cqe_next; \
else \
(elm)->field.cqe_prev->field.cqe_next = \
(elm)->field.cqe_next; \
QUEUEDEBUG_CIRCLEQ_POSTREMOVE((elm), field) \
} while (/*CONSTCOND*/0)
#define CIRCLEQ_FOREACH(var, head, field) \
for ((var) = ((head)->cqh_first); \
(var) != (const void *)(head); \
(var) = ((var)->field.cqe_next))
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
for ((var) = ((head)->cqh_last); \
(var) != (const void *)(head); \
(var) = ((var)->field.cqe_prev))
/*
* Circular queue access methods.
*/
#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
#define CIRCLEQ_LOOP_NEXT(head, elm, field) \
(((elm)->field.cqe_next == (void *)(head)) \
? ((head)->cqh_first) \
: (elm->field.cqe_next))
#define CIRCLEQ_LOOP_PREV(head, elm, field) \
(((elm)->field.cqe_prev == (void *)(head)) \
? ((head)->cqh_last) \
: (elm->field.cqe_prev))
#endif /* !_ELF_SYS_QUEUE_H_ */
+29
Переглянути файл
@@ -0,0 +1,29 @@
##
########################################################################################################################
#
# Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
#
########################################################################################################################
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common)
if(WIN32)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common/win32)
else()
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common/win32/sys)
endif()
add_definitions(-DBSD_LIBELF -DUSE_MEMFILE)
file(GLOB sources
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/*.c
${CMAKE_CURRENT_SOURCE_DIR}/*.h
)
add_library(oclelf STATIC ${sources})
set_target_properties(oclelf PROPERTIES POSITION_INDEPENDENT_CODE ON)
+12
Переглянути файл
@@ -0,0 +1,12 @@
# $FreeBSD$
# $NetBSD$
libelf: a BSD-licensed implementation of the ELF(3)/GELF(3) API.
Documentation:
* Manual page elf.3 contains an overview of the library. Other
manual pages document individual APIs in the library.
* A tutorial "libelf by Example" is available at:
http://people.freebsd.org/~jkoshy/download/libelf/article.html
For ongoing development please see http://elftoolchain.sourceforge.net/
+64
Переглянути файл
@@ -0,0 +1,64 @@
: README.build -- notes on the build process
The "Makefile" in this directory uses BSD make(1) syntax. If you are
trying to build this library on a platform that does not have a
pre-built BSD compatible make(1), then you could try porting NetBSD's
make(1). NetBSD's make(1) is available at:
http://www.crufty.net/help/sjg/bmake.html
: Supporting cross builds
In the general case, libelf may be built for a target operating system
and machine architecture that is different from the host operating
system and machine architecture that the compilation is happening on.
For example, compilation could be running on a Linux/i386 host, with
target binaries being created for a NetBSD/sparc64 system.
To support cross building:
- The top-level "Makefile" pulls in the appropriate make rules for the
target system.
Inside of makefiles, we determine the target OS by looking at the
contents of the ${unix} make variable. The top-level makefile then
includes any target specific makefiles if they exist.
- Operating systems differ in the names and locations of the headers
where their ELF types are defined. They also differ in the set of
ELF types supported. Inside of libelf's implementation these
differences are abstracted out by the auxiliary header
"_libelf_config.h".
: OS Specific Configuration :
:: Debian ::
The following packages are needed for the build:
- `build-essential'
- `m4'
- `freebsd-buildutils' or `freebsd5-buildutils'
You would need to use `freebsd-make' instead of GNU make to build
the tools. You would also need to place /usr/lib/freebsd in the
shell's `PATH', preferably at the beginning.
:: FreeBSD ::
libelf should build out of the box on FreeBSD versions later than 6.0.
:: NetBSD ::
libelf should build out of the box on NetBSD versions later than 4.0.
:: Ubuntu ::
See the section on 'Debian' above.
: Porting resources on the 'net
The 'predef' project [http://predef.sourceforge.net/] has a
comprehensive list of CPP macros predefined by various OSes.
+97
Переглянути файл
@@ -0,0 +1,97 @@
/*
* $Id: Version.map 2033 2011-10-23 09:21:13Z jkoshy $
*
* $FreeBSD: src/lib/libelf/Version.map,v 1.3 2007/04/29 14:05:22 deischen Exp $
*/
FBSD_1.0 {
global:
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;
elf_begin;
elf_cntl;
elf_end;
elf_errmsg;
elf_errno;
elf_fill;
elf_flagarhdr;
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_getphdrnum;
elf_getphnum;
elf_getshdrnum;
elf_getshnum;
elf_getshdrstrndx;
elf_getshstrndx;
elf_hash;
elf_kind;
elf_memory;
elf_ndxscn;
elf_newdata;
elf_newscn;
elf_next;
elf_nextscn;
elf_rand;
elf_rawdata;
elf_rawfile;
elf_setshstrndx;
elf_strptr;
elf_update;
elf_version;
gelf_checksum;
gelf_fsize;
gelf_getcap;
gelf_getclass;
gelf_getdyn;
gelf_getehdr;
gelf_getmove;
gelf_getphdr;
gelf_getrel;
gelf_getrela;
gelf_getshdr;
gelf_getsym;
gelf_getsyminfo;
gelf_getsymshndx;
gelf_newehdr;
gelf_newphdr;
gelf_update_cap;
gelf_update_dyn;
gelf_update_ehdr;
gelf_update_move;
gelf_update_phdr;
gelf_update_rel;
gelf_update_rela;
gelf_update_shdr;
gelf_update_sym;
gelf_update_syminfo;
gelf_update_symshndx;
gelf_xlatetof;
gelf_xlatetom;
local:
*;
};
+216
Переглянути файл
@@ -0,0 +1,216 @@
/*-
* Copyright (c) 2006,2008-2011 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: _libelf.h 1921 2011-09-23 08:04:02Z jkoshy $
*/
#ifndef __LIBELF_H_
#define __LIBELF_H_
#include <limits.h>
#include <sys/queue.h>
#include "_libelf_config.h"
#include "_elftc.h"
/*
* Library-private data structures.
*/
#define LIBELF_MSG_SIZE 256
struct _libelf_globals {
int libelf_arch;
unsigned int libelf_byteorder;
int libelf_class;
int libelf_error;
int libelf_fillchar;
unsigned int libelf_version;
char libelf_msg[LIBELF_MSG_SIZE];
};
extern struct _libelf_globals _libelf;
#define LIBELF_PRIVATE(N) (_libelf.libelf_##N)
#define LIBELF_ELF_ERROR_MASK 0xFF
#define LIBELF_OS_ERROR_SHIFT 8
#define LIBELF_SET_ERROR(E, O) do { \
LIBELF_PRIVATE(error) = ((ELF_E_##E & LIBELF_ELF_ERROR_MASK)| \
((O) << LIBELF_OS_ERROR_SHIFT)); \
} while (0)
#define LIBELF_ADJUST_AR_SIZE(S) (((S) + 1U) & ~1U)
/*
* Flags for library internal use. These use the upper 16 bits of the
* `e_flags' field.
*/
#define LIBELF_F_API_MASK 0x00FFFF /* Flags defined by the API. */
#define LIBELF_F_AR_HEADER 0x010000 /* translated header available */
#define LIBELF_F_AR_VARIANT_SVR4 0x020000 /* BSD style ar(1) archive */
#define LIBELF_F_DATA_MALLOCED 0x040000 /* whether data was malloc'ed */
#define LIBELF_F_RAWFILE_MALLOC 0x080000 /* whether e_rawfile was malloc'ed */
#define LIBELF_F_RAWFILE_MMAP 0x100000 /* whether e_rawfile was mmap'ed */
#define LIBELF_F_SHDRS_LOADED 0x200000 /* whether all shdrs were read in */
#define LIBELF_F_SPECIAL_FILE 0x400000 /* non-regular file */
struct _Elf_Mem {
void (*dealloc)(void*);
void* (*alloc)(size_t);
};
struct _Elf {
int e_activations; /* activation count */
unsigned int e_byteorder; /* ELFDATA* */
int e_class; /* ELFCLASS* */
Elf_Cmd e_cmd; /* ELF_C_* used at creation time */
int e_fd; /* associated file descriptor */
unsigned int e_flags; /* ELF_F_* & LIBELF_F_* flags */
Elf_Kind e_kind; /* ELF_K_* */
Elf *e_parent; /* non-NULL for archive members */
char *e_rawfile; /* uninterpreted bytes */
size_t e_rawsize; /* size of uninterpreted bytes */
unsigned int e_version; /* file version */
/* AMD Memory interface */
struct _Elf_Mem e_mem;
/*
* Header information for archive members. See the
* LIBELF_F_AR_HEADER flag.
*/
union {
Elf_Arhdr *e_arhdr; /* translated header */
char *e_rawhdr; /* untranslated header */
} e_hdr;
union {
struct { /* ar(1) archives */
off_t e_next; /* set by elf_rand()/elf_next() */
int e_nchildren;
char *e_rawstrtab; /* file name strings */
size_t e_rawstrtabsz;
char *e_rawsymtab; /* symbol table */
size_t e_rawsymtabsz;
Elf_Arsym *e_symtab;
size_t e_symtabsz;
} e_ar;
struct { /* regular ELF files */
union {
Elf32_Ehdr *e_ehdr32;
Elf64_Ehdr *e_ehdr64;
} e_ehdr;
union {
Elf32_Phdr *e_phdr32;
Elf64_Phdr *e_phdr64;
} e_phdr;
STAILQ_HEAD(, _Elf_Scn) e_scn; /* section list */
size_t e_nphdr; /* number of Phdr entries */
size_t e_nscn; /* number of sections */
size_t e_strndx; /* string table section index */
} e_elf;
} e_u;
};
struct _Elf_Scn {
union {
Elf32_Shdr s_shdr32;
Elf64_Shdr s_shdr64;
} s_shdr;
STAILQ_HEAD(, _Elf_Data) s_data; /* list of Elf_Data descriptors */
STAILQ_HEAD(, _Elf_Data) s_rawdata; /* raw data for this section */
STAILQ_ENTRY(_Elf_Scn) s_next;
struct _Elf *s_elf; /* parent ELF descriptor */
unsigned int s_flags; /* flags for the section as a whole */
size_t s_ndx; /* index# for this section */
uint64_t s_offset; /* managed by elf_update() */
uint64_t s_rawoff; /* original offset in the file */
uint64_t s_size; /* managed by elf_update() */
};
enum {
ELF_TOFILE,
ELF_TOMEMORY
};
#define LIBELF_COPY_U32(DST,SRC,NAME) do { \
if ((SRC)->NAME > UINT_MAX) { \
LIBELF_SET_ERROR(RANGE, 0); \
return (0); \
} \
(DST)->NAME = (SRC)->NAME; \
} while (0)
#define LIBELF_COPY_S32(DST,SRC,NAME) do { \
if ((SRC)->NAME > INT_MAX || \
(SRC)->NAME < INT_MIN) { \
LIBELF_SET_ERROR(RANGE, 0); \
return (0); \
} \
(DST)->NAME = (SRC)->NAME; \
} while (0)
/*
* Function Prototypes.
*/
__BEGIN_DECLS
Elf_Data *_libelf_allocate_data(Elf_Scn *_s);
Elf *_libelf_allocate_elf(Elf_Mem *mem);
Elf_Scn *_libelf_allocate_scn(Elf *_e, size_t _ndx);
Elf_Arhdr *_libelf_ar_gethdr(Elf *_e);
Elf *_libelf_ar_open(Elf *_e);
Elf *_libelf_ar_open_member(int _fd, Elf_Cmd _c, Elf *_ar, Elf_Mem *mem);
int _libelf_ar_get_member(char *_s, size_t _sz, int _base, size_t *_ret);
Elf_Arsym *_libelf_ar_process_bsd_symtab(Elf *_ar, size_t *_dst);
Elf_Arsym *_libelf_ar_process_svr4_symtab(Elf *_ar, size_t *_dst);
unsigned long _libelf_checksum(Elf *_e, int _elfclass);
void *_libelf_ehdr(Elf *_e, int _elfclass, int _allocate);
int _libelf_falign(Elf_Type _t, int _elfclass);
size_t _libelf_fsize(Elf_Type _t, int _elfclass, unsigned int _version,
size_t count);
int (*_libelf_get_translator(Elf_Type _t, int _direction, int _elfclass))
(char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap);
void *_libelf_getphdr(Elf *_e, int _elfclass);
void *_libelf_getshdr(Elf_Scn *_scn, int _elfclass);
void _libelf_init_elf(Elf *_e, Elf_Kind _kind);
int _libelf_load_section_headers(Elf *e, void *ehdr);
int _libelf_malign(Elf_Type _t, int _elfclass);
size_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version);
void *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count);
Elf_Data *_libelf_release_data(Elf_Data *_d);
Elf *_libelf_release_elf(Elf *_e);
Elf_Scn *_libelf_release_scn(Elf_Scn *_s);
int _libelf_setphnum(Elf *_e, void *_eh, int _elfclass, size_t _phnum);
int _libelf_setshnum(Elf *_e, void *_eh, int _elfclass, size_t _shnum);
int _libelf_setshstrndx(Elf *_e, void *_eh, int _elfclass,
size_t _shstrndx);
Elf_Data *_libelf_xlate(Elf_Data *_d, const Elf_Data *_s,
unsigned int _encoding, int _elfclass, int _direction);
int _libelf_xlate_shtype(uint32_t _sht);
__END_DECLS
#endif /* __LIBELF_H_ */
+55
Переглянути файл
@@ -0,0 +1,55 @@
/*-
* Copyright (c) 2010 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: _libelf_ar.h 2032 2011-10-23 09:07:00Z jkoshy $
*/
#ifndef __LIBELF_AR_H_
#define __LIBELF_AR_H_
/*
* Prototypes and declarations needed by libelf's ar(1) archive
* handling code.
*/
#include <ar.h>
#define LIBELF_AR_BSD_EXTENDED_NAME_PREFIX "#1/"
#define LIBELF_AR_BSD_SYMTAB_NAME "__.SYMDEF"
#define LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE \
(sizeof(LIBELF_AR_BSD_EXTENDED_NAME_PREFIX) - 1)
#define IS_EXTENDED_BSD_NAME(NAME) \
(strncmp((NAME), LIBELF_AR_BSD_EXTENDED_NAME_PREFIX, \
LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE) == 0)
char *_libelf_ar_get_string(const char *_buf, size_t _sz, int _rawname,
int _svr4names);
char *_libelf_ar_get_raw_name(const struct ar_hdr *_arh);
char *_libelf_ar_get_translated_name(const struct ar_hdr *_arh, Elf *_ar);
int _libelf_ar_get_number(const char *_buf, size_t _sz, int _base,
size_t *_ret);
#endif /* __LIBELF_AR_H_ */
+288
Переглянути файл
@@ -0,0 +1,288 @@
/*-
* Copyright (c) 2008-2011 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: _libelf_config.h 2032 2011-10-23 09:07:00Z jkoshy $
*/
#ifdef __FreeBSD__
#define LIBELF_VCSID(ID) __FBSDID(ID)
/*
* Define LIBELF_{ARCH,BYTEORDER,CLASS} based on the machine architecture.
* See also: <machine/elf.h>.
*/
#if defined(__amd64__)
#define LIBELF_ARCH EM_X86_64
#define LIBELF_BYTEORDER ELFDATA2LSB
#define LIBELF_CLASS ELFCLASS64
#elif defined(__arm__)
#define LIBELF_ARCH EM_ARM
#if defined(__ARMEB__) /* Big-endian ARM. */
#define LIBELF_BYTEORDER ELFDATA2MSB
#else
#define LIBELF_BYTEORDER ELFDATA2LSB
#endif
#define LIBELF_CLASS ELFCLASS32
#elif defined(__i386__)
#define LIBELF_ARCH EM_386
#define LIBELF_BYTEORDER ELFDATA2LSB
#define LIBELF_CLASS ELFCLASS32
#elif defined(__ia64__)
#define LIBELF_ARCH EM_IA_64
#define LIBELF_BYTEORDER ELFDATA2LSB
#define LIBELF_CLASS ELFCLASS64
#elif defined(__mips__)
#define LIBELF_ARCH EM_MIPS
#if defined(__MIPSEB__)
#define LIBELF_BYTEORDER ELFDATA2MSB
#else
#define LIBELF_BYTEORDER ELFDATA2LSB
#endif
#define LIBELF_CLASS ELFCLASS32
#elif defined(__powerpc__)
#define LIBELF_ARCH EM_PPC
#define LIBELF_BYTEORDER ELFDATA2MSB
#define LIBELF_CLASS ELFCLASS32
#elif defined(__sparc__)
#define LIBELF_ARCH EM_SPARCV9
#define LIBELF_BYTEORDER ELFDATA2MSB
#define LIBELF_CLASS ELFCLASS64
#else
#error Unknown FreeBSD architecture.
#endif
#endif /* __FreeBSD__ */
#ifdef __NetBSD__
#include <machine/elf_machdep.h>
#define LIBELF_VCSID(ID) __RCSID(ID)
#if !defined(ARCH_ELFSIZE)
#error ARCH_ELFSIZE is not defined.
#endif
#if ARCH_ELFSIZE == 32
#define LIBELF_ARCH ELF32_MACHDEP_ID
#define LIBELF_BYTEORDER ELF32_MACHDEP_ENDIANNESS
#define LIBELF_CLASS ELFCLASS32
#define Elf_Note Elf32_Nhdr
#else
#define LIBELF_ARCH ELF64_MACHDEP_ID
#define LIBELF_BYTEORDER ELF64_MACHDEP_ENDIANNESS
#define LIBELF_CLASS ELFCLASS64
#define Elf_Note Elf64_Nhdr
#endif
#endif /* __NetBSD__ */
/*
* GNU & Linux compatibility.
*
* `__linux__' is defined in an environment runs the Linux kernel and glibc.
* `__GNU__' is defined in an environment runs a GNU kernel (Hurd) and glibc.
* `__GLIBC__' is defined for an environment that runs glibc over a non-GNU
* kernel such as GNU/kFreeBSD.
*/
#if defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)
#if defined(__linux__)
#include "native-elf-format.h"
#define LIBELF_CLASS ELFTC_CLASS
#define LIBELF_ARCH ELFTC_ARCH
#define LIBELF_BYTEORDER ELFTC_BYTEORDER
#endif /* defined(__linux__) */
#define LIBELF_VCSID(ID)
#if LIBELF_CLASS == ELFCLASS32
#define Elf_Note Elf32_Nhdr
#elif LIBELF_CLASS == ELFCLASS64
#define Elf_Note Elf64_Nhdr
#else
#error LIBELF_CLASS needs to be one of ELFCLASS32 or ELFCLASS64
#endif
#define roundup2 roundup
#endif /* defined(__linux__) || defined(__GNU__) || defined(__GLIBC__) */
/*
* Common configuration for the GNU environment.
*/
#define LIBELF_CONFIG_ADDR 1
#define LIBELF_CONFIG_BYTE 1
#define LIBELF_CONFIG_DYN 1
#define LIBELF_CONFIG_EHDR 1
#define LIBELF_CONFIG_HALF 1
#define LIBELF_CONFIG_MOVEP 1
#define LIBELF_CONFIG_NOTE 1
#define LIBELF_CONFIG_OFF 1
#define LIBELF_CONFIG_PHDR 1
#define LIBELF_CONFIG_REL 1
#define LIBELF_CONFIG_RELA 1
#define LIBELF_CONFIG_SHDR 1
#define LIBELF_CONFIG_SWORD 1
#define LIBELF_CONFIG_SXWORD 1
#define LIBELF_CONFIG_SYM 1
#define LIBELF_CONFIG_VDEF 1
#define LIBELF_CONFIG_VNEED 1
#define LIBELF_CONFIG_WORD 1
#define LIBELF_CONFIG_XWORD 1
#if defined(WIN32)
#include "native-elf-format.h"
#define LIBELF_CLASS ELFTC_CLASS
#define LIBELF_ARCH ELFTC_ARCH
#define LIBELF_BYTEORDER ELFTC_BYTEORDER
#define LIBELF_CONFIG_ADDR 1
#define LIBELF_CONFIG_BYTE 1
#define LIBELF_CONFIG_DYN 1
#define LIBELF_CONFIG_EHDR 1
#define LIBELF_CONFIG_HALF 1
#define LIBELF_CONFIG_MOVEP 1
#define LIBELF_CONFIG_OFF 1
#define LIBELF_CONFIG_PHDR 1
#define LIBELF_CONFIG_REL 1
#define LIBELF_CONFIG_RELA 1
#define LIBELF_CONFIG_SHDR 1
#define LIBELF_CONFIG_SWORD 1
#define LIBELF_CONFIG_SXWORD 1
#define LIBELF_CONFIG_SYM 1
#define LIBELF_CONFIG_WORD 1
#define LIBELF_CONFIG_XWORD 1
#define LIBELF_VCSID(ID)
#define roundup2 roundup
#endif // defined(WIN32)
#ifndef LIBELF_CONFIG_GNUHASH
#define LIBELF_CONFIG_GNUHASH 1
/*
* The header for GNU-style hash sections.
*/
typedef struct {
u_int32_t gh_nbuckets; /* Number of hash buckets. */
u_int32_t gh_symndx; /* First visible symbol in .dynsym. */
u_int32_t gh_maskwords; /* #maskwords used in bloom filter. */
u_int32_t gh_shift2; /* Bloom filter shift count. */
} Elf_GNU_Hash_Header;
#endif
#if defined(USE_MEMFILE)
#include "memfile.h"
#if !defined(read)
#define read(f, b, l) mem_read((f), (b), (l))
#endif
#if !defined(write)
#define write(f, b, l) mem_write((f), (b), (l))
#endif
#if !defined(lseek)
#define lseek(f, l, w) mem_lseek((f), (l), (w))
#endif
#if !defined(fstat)
#define fstat(f, b) mem_fstat((f), (struct stat*)(b))
#endif
#if !defined(_fstat64i32)
#define _fstat64i32(f, b) mem_fstat((f), (struct stat*)(b))
#endif
#if !defined(_fstat32i64)
#define _fstat32i64(f, b) mem_fstat((f), (struct stat*)(b))
#endif
#if !defined(_fstat32)
#define _fstat32(f, b) mem_fstat((f), (struct stat*)(b))
#endif
#if !defined(_fstat64)
#define _fstat64(f, b) mem_fstat((f), (struct stat*)(b))
#endif
#if !defined(ftruncate)
#define ftruncate(f, l) mem_ftruncate((f), (size_t)(l))
#endif
#if !defined(_chsize)
#define _chsize(f, l) mem_ftruncate((f), (size_t)(l))
#endif
#if !defined(mmap)
#define mmap mem_mmap
#endif
#if !defined(mem_munmap)
#define munmap mem_munmap
#endif
#else // !USE_MEMFILE
#if !defined(mmap)
#if defined(WIN32)
#define mmap w32_mmap
#else
#define mmap mmap
#endif
#endif
#if !defined(mem_munmap)
#if defined(WIN32)
#define munmap w32_munmap
#else
#define munmap munmap
#endif
#endif
#endif //USE_MEMFILE
+41
Переглянути файл
@@ -0,0 +1,41 @@
/*-
* Copyright (c) 2006,2008,2011 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf.c 1345 2011-01-01 11:17:52Z jkoshy $");
struct _libelf_globals _libelf = {
/*.libelf_arch = */LIBELF_ARCH,
/*.libelf_byteorder = */LIBELF_BYTEORDER,
/*.libelf_class = */LIBELF_CLASS,
/*.libelf_error = */0,
/*.libelf_fillchar = */0,
/*.libelf_version = */EV_NONE,
{ 0 }
};
+334
Переглянути файл
@@ -0,0 +1,334 @@
/*-
* Copyright (c) 2006,2008-2011 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <sys/types.h>
#if !defined(WIN32)
#include <sys/errno.h>
#include <sys/mman.h>
#else
#ifndef PROT_READ
#define PROT_READ FILE_MAP_READ
#endif
#ifndef MAP_PRIVATE
#define MAP_PRIVATE FILE_MAP_COPY
#endif
#ifndef MAP_FAILED
#define MAP_FAILED NULL
#endif
#include <Windows.h>
#endif
#include <sys/stat.h>
#include <ar.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <libelf.h>
#include <stdlib.h>
#include <stdio.h>
#if !defined(WIN32)
#include <unistd.h>
#else
#include "compat.h"
#endif
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_begin.c 1923 2011-09-23 09:01:13Z jkoshy $");
#define _LIBELF_INITSIZE (64*1024)
/*
* Read from a device file, pipe or socket.
*/
static void *
_libelf_read_special_file(int fd, size_t *fsz)
{
ssize_t readsz;
size_t bufsz, datasz;
unsigned char *buf, *t;
datasz = 0;
readsz = 0;
bufsz = _LIBELF_INITSIZE;
if ((buf = malloc(bufsz)) == NULL)
goto resourceerror;
/*
* Read data from the file descriptor till we reach EOF, or
* till an error is encountered.
*/
do {
/* Check if we need to expand the data buffer. */
if (datasz == bufsz) {
bufsz *= 2;
if ((t = realloc(buf, bufsz)) == NULL)
goto resourceerror;
buf = t;
}
do {
readsz = bufsz - datasz;
t = buf + datasz;
if ((readsz = read(fd, t, readsz)) <= 0)
break;
datasz += readsz;
} while (datasz < bufsz);
} while (readsz > 0);
if (readsz < 0) {
LIBELF_SET_ERROR(IO, errno);
goto error;
}
assert(readsz == 0);
/*
* Free up extra buffer space.
*/
if (bufsz > datasz) {
if (datasz > 0) {
if ((t = realloc(buf, datasz)) == NULL)
goto resourceerror;
buf = t;
} else { /* Zero bytes read. */
LIBELF_SET_ERROR(ARGUMENT, 0);
free(buf);
buf = NULL;
}
}
*fsz = datasz;
return (buf);
resourceerror:
LIBELF_SET_ERROR(RESOURCE, 0);
error:
if (buf != NULL)
free(buf);
return (NULL);
}
static Elf *
_libelf_open_object(int fd, Elf_Cmd c, Elf_Mem *mem)
{
Elf *e;
void *m;
mode_t mode;
size_t fsize;
struct stat sb;
unsigned int flags;
assert(c == ELF_C_READ || c == ELF_C_RDWR || c == ELF_C_WRITE);
if (fstat(fd, &sb) < 0) {
LIBELF_SET_ERROR(IO, errno);
return (NULL);
}
mode = sb.st_mode;
fsize = (size_t) sb.st_size;
/*
* Reject unsupported file types.
*/
if (!S_ISREG(mode) && !S_ISCHR(mode)
#if !defined(WIN32)
&& !S_ISFIFO(mode) &&
!S_ISSOCK(mode)
#endif
) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
/*
* For ELF_C_WRITE mode, allocate and return a descriptor.
* For ELF_C_RDWR mode, if the file is empty, allocate and return.
*/
if (c == ELF_C_WRITE || (c == ELF_C_RDWR && !fsize)) {
if ((e = _libelf_allocate_elf(mem)) != NULL) {
_libelf_init_elf(e, ELF_K_ELF);
e->e_byteorder = LIBELF_PRIVATE(byteorder);
e->e_fd = fd;
e->e_cmd = c;
if (!S_ISREG(mode))
e->e_flags |= LIBELF_F_SPECIAL_FILE;
}
return (e);
}
/*
* ELF_C_READ and ELF_C_RDWR mode.
*/
m = NULL;
flags = 0;
if (S_ISREG(mode)) {
/*
* Always map regular files in with 'PROT_READ'
* permissions.
*
* For objects opened in ELF_C_RDWR mode, when
* elf_update(3) is called, we remove this mapping,
* write file data out using write(2), and map the new
* contents back.
*/
if ((m = mmap(NULL, fsize, PROT_READ, MAP_PRIVATE, fd,
(off_t) 0)) == MAP_FAILED) {
LIBELF_SET_ERROR(IO, errno);
return (NULL);
}
flags = LIBELF_F_RAWFILE_MMAP;
#if 0
m = mem.alloc(fsize);
if (!fread(m, 1, fsize, _fdopen(fd, "w+b"))) {
LIBELF_SET_ERROR(IO, errno);
mem.dealloc(m);
return(NULL);
}
flags = LIBELF_F_RAWFILE_MALLOC;
#endif
} else if ((m = _libelf_read_special_file(fd, &fsize)) != NULL)
flags = LIBELF_F_RAWFILE_MALLOC | LIBELF_F_SPECIAL_FILE;
else
return (NULL);
if ((e = elf_memory(m, fsize, mem)) == NULL) {
assert((flags & LIBELF_F_RAWFILE_MALLOC) ||
(flags & LIBELF_F_RAWFILE_MMAP));
if (flags & LIBELF_F_RAWFILE_MMAP)
(void) munmap(m, fsize);
else
e->e_mem.dealloc(m);
return (NULL);
}
/* ar(1) archives aren't supported in RDWR mode. */
if (c == ELF_C_RDWR && e->e_kind == ELF_K_AR) {
(void) elf_end(e);
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
e->e_flags |= flags;
e->e_fd = fd;
e->e_cmd = c;
return (e);
}
Elf *
elf_begin(int fd, Elf_Cmd c, Elf *a, Elf_Mem *mem)
{
Elf *e;
e = NULL;
if (LIBELF_PRIVATE(version) == EV_NONE) {
LIBELF_SET_ERROR(SEQUENCE, 0);
return (NULL);
}
switch (c) {
case ELF_C_NULL:
return (NULL);
case ELF_C_WRITE:
/*
* The ELF_C_WRITE command is required to ignore the
* descriptor passed in.
*/
a = NULL;
break;
case ELF_C_RDWR:
if (a != NULL && a->e_kind == ELF_K_AR) { /* not allowed for ar(1) archives. */
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
/*FALLTHROUGH*/
case ELF_C_READ:
/*
* Descriptor `a' could be for a regular ELF file, or
* for an ar(1) archive. If descriptor `a' was opened
* using a valid file descriptor, we need to check if
* the passed in `fd' value matches the original one.
*/
if (a &&
((a->e_fd != -1 && a->e_fd != fd) || c != a->e_cmd)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
break;
default:
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if (a == NULL)
e = _libelf_open_object(fd, c, mem);
else if (a->e_kind == ELF_K_AR)
e = _libelf_ar_open_member(a->e_fd, c, a, mem);
else
(e = a)->e_activations++;
return (e);
}
#if defined(WIN32)
// This code taken from:
// http://git.661346.n2.nabble.com/PATCH-mmap-implementation-for-mingw-td1560056.html
// This code is in public domain according to the FAQ here:
// http://www.mingw.org/wiki/FAQ
// http://www.mingw.org/license
// FIXME: This needs to be more robust to the protection and flag options.
void *w32_mmap(void *start, size_t length, int prot, int flags, int fd,
unsigned offset)
{
HANDLE handle;
if (start != NULL || !(flags & MAP_PRIVATE))
assert(!"Invalid usage of mingw_mmap");
handle = CreateFileMapping((HANDLE)_get_osfhandle(fd), NULL, PAGE_READONLY, 0, 0, NULL);
if (handle != NULL) {
start = MapViewOfFile(handle, flags, 0, offset,
length);
CloseHandle(handle);
}
return start;
}
int w32_munmap(void *start, size_t length) {
UnmapViewOfFile(start);
return 0;
}
#endif
+58
Переглянути файл
@@ -0,0 +1,58 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_cntl.c 189 2008-07-20 10:38:08Z jkoshy $");
int
elf_cntl(Elf *e, Elf_Cmd c)
{
if (e == NULL ||
(c != ELF_C_FDDONE && c != ELF_C_FDREAD)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (-1);
}
if (e->e_parent) {
LIBELF_SET_ERROR(ARCHIVE, 0);
return (-1);
}
if (c == ELF_C_FDREAD) {
if (e->e_cmd == ELF_C_WRITE) {
LIBELF_SET_ERROR(MODE, 0);
return (-1);
}
else
return (0);
}
e->e_fd = -1;
return 0;
}
+254
Переглянути файл
@@ -0,0 +1,254 @@
/*-
* Copyright (c) 2006,2008,2011 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <assert.h>
#include <errno.h>
#include <libelf.h>
#include <stdlib.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_data.c 1765 2011-08-22 05:59:05Z jkoshy $");
Elf_Data *
elf_getdata(Elf_Scn *s, Elf_Data *d)
{
Elf *e;
size_t fsz, msz, count;
int elfclass, elftype;
unsigned int sh_type;
uint64_t sh_align, sh_offset, sh_size;
int (*xlate)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap);
if (s == NULL || (e = s->s_elf) == NULL ||
(d != NULL && s != d->d_scn)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
assert(e->e_kind == ELF_K_ELF);
if (d == NULL && (d = STAILQ_FIRST(&s->s_data)) != NULL)
return (d);
if (d != NULL)
return (STAILQ_NEXT(d, d_next));
if (e->e_rawfile == NULL) {
/*
* In the ELF_C_WRITE case, there is no source that
* can provide data for the section.
*/
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
elfclass = e->e_class;
assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64);
if (elfclass == ELFCLASS32) {
sh_type = s->s_shdr.s_shdr32.sh_type;
sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset;
sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size;
sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign;
} else {
sh_type = s->s_shdr.s_shdr64.sh_type;
sh_offset = s->s_shdr.s_shdr64.sh_offset;
sh_size = s->s_shdr.s_shdr64.sh_size;
sh_align = s->s_shdr.s_shdr64.sh_addralign;
}
if (sh_type == SHT_NULL) {
LIBELF_SET_ERROR(SECTION, 0);
return (NULL);
}
if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST ||
elftype > ELF_T_LAST || (sh_type != SHT_NOBITS &&
sh_offset + sh_size > (uint64_t) e->e_rawsize)) {
LIBELF_SET_ERROR(SECTION, 0);
return (NULL);
}
if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize)
(elftype, (size_t) 1, e->e_version)) == 0) {
LIBELF_SET_ERROR(UNIMPL, 0);
return (NULL);
}
if (sh_size % fsz) {
LIBELF_SET_ERROR(SECTION, 0);
return (NULL);
}
count = sh_size / fsz;
msz = _libelf_msize(elftype, elfclass, e->e_version);
assert(msz > 0);
if ((d = _libelf_allocate_data(s)) == NULL)
return (NULL);
d->d_buf = NULL;
d->d_off = 0;
d->d_align = sh_align;
d->d_size = msz * count;
d->d_type = elftype;
d->d_version = e->e_version;
if (sh_type == SHT_NOBITS || sh_size == 0) {
STAILQ_INSERT_TAIL(&s->s_data, d, d_next);
return (d);
}
if ((d->d_buf = e->e_mem.alloc(msz*count)) == NULL) {
(void) _libelf_release_data(d);
LIBELF_SET_ERROR(RESOURCE, 0);
return (NULL);
}
d->d_flags |= LIBELF_F_DATA_MALLOCED;
xlate = _libelf_get_translator(elftype, ELF_TOMEMORY, elfclass);
if (!(*xlate)(d->d_buf, d->d_size, e->e_rawfile + sh_offset, count,
e->e_byteorder != LIBELF_PRIVATE(byteorder))) {
_libelf_release_data(d);
LIBELF_SET_ERROR(DATA, 0);
return (NULL);
}
STAILQ_INSERT_TAIL(&s->s_data, d, d_next);
return (d);
}
Elf_Data *
elf_newdata(Elf_Scn *s)
{
Elf *e;
Elf_Data *d;
if (s == NULL || (e = s->s_elf) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
assert(e->e_kind == ELF_K_ELF);
/*
* elf_newdata() has to append a data descriptor, so
* bring in existing section data if not already present.
*/
if (e->e_rawfile && s->s_size > 0 && STAILQ_EMPTY(&s->s_data))
if (elf_getdata(s, NULL) == NULL)
return (NULL);
if ((d = _libelf_allocate_data(s)) == NULL)
return (NULL);
STAILQ_INSERT_TAIL(&s->s_data, d, d_next);
d->d_align = 1;
d->d_buf = NULL;
d->d_off = (uint64_t) ~0;
d->d_size = 0;
d->d_type = ELF_T_BYTE;
d->d_version = LIBELF_PRIVATE(version);
(void) elf_flagscn(s, ELF_C_SET, ELF_F_DIRTY);
return (d);
}
/*
* Retrieve a data descriptor for raw (untranslated) data for section
* `s'.
*/
Elf_Data *
elf_rawdata(Elf_Scn *s, Elf_Data *d)
{
Elf *e;
int elf_class;
uint32_t sh_type;
uint64_t sh_align, sh_offset, sh_size;
if (s == NULL || (e = s->s_elf) == NULL || e->e_rawfile == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
assert(e->e_kind == ELF_K_ELF);
if (d == NULL && (d = STAILQ_FIRST(&s->s_rawdata)) != NULL)
return (d);
if (d != NULL)
return (STAILQ_NEXT(d, d_next));
elf_class = e->e_class;
assert(elf_class == ELFCLASS32 || elf_class == ELFCLASS64);
if (elf_class == ELFCLASS32) {
sh_type = s->s_shdr.s_shdr32.sh_type;
sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset;
sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size;
sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign;
} else {
sh_type = s->s_shdr.s_shdr64.sh_type;
sh_offset = s->s_shdr.s_shdr64.sh_offset;
sh_size = s->s_shdr.s_shdr64.sh_size;
sh_align = s->s_shdr.s_shdr64.sh_addralign;
}
if (sh_type == SHT_NULL)
return (NULL);
if ((d = _libelf_allocate_data(s)) == NULL)
return (NULL);
d->d_buf = (sh_type == SHT_NOBITS || sh_size == 0) ? NULL :
e->e_rawfile + sh_offset;
d->d_off = 0;
d->d_align = sh_align;
d->d_size = sh_size;
d->d_type = ELF_T_BYTE;
d->d_version = e->e_version;
STAILQ_INSERT_TAIL(&s->s_rawdata, d, d_next);
return (d);
}
void
elf_removedata(Elf_Scn *s, Elf_Data *d)
{
STAILQ_REMOVE(&s->s_data, d, _Elf_Data, d_next);
d = _libelf_release_data(d);
}
+99
Переглянути файл
@@ -0,0 +1,99 @@
/*-
* Copyright (c) 2006,2008-2009,2011 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if !defined(WIN32)
#include <sys/mman.h>
#endif
#include <assert.h>
#include <libelf.h>
#include <stdlib.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_end.c 1922 2011-09-23 08:04:33Z jkoshy $");
int
elf_end(Elf *e)
{
Elf *sv;
Elf_Scn *scn, *tscn;
if (e == NULL || e->e_activations == 0)
return (0);
if (--e->e_activations > 0)
return (e->e_activations);
assert(e->e_activations == 0);
while (e && e->e_activations == 0) {
switch (e->e_kind) {
case ELF_K_AR:
/*
* If we still have open child descriptors, we
* need to defer reclaiming resources till all
* the child descriptors for the archive are
* closed.
*/
if (e->e_u.e_ar.e_nchildren > 0)
return (0);
break;
case ELF_K_ELF:
/*
* Reclaim all section descriptors.
*/
STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next,
tscn)
scn = _libelf_release_scn(scn);
break;
case ELF_K_NUM:
assert(0);
default:
break;
}
if (e->e_rawfile) {
if (e->e_flags & LIBELF_F_RAWFILE_MMAP)
#if !defined(WIN32)
(void) munmap(e->e_rawfile, e->e_rawsize);
#else
abort();
#endif
else if (e->e_flags & LIBELF_F_RAWFILE_MALLOC)
e->e_mem.dealloc(e->e_rawfile);
}
sv = e;
if ((e = e->e_parent) != NULL)
e->e_u.e_ar.e_nchildren--;
sv = _libelf_release_elf(sv);
}
return (0);
}
+88
Переглянути файл
@@ -0,0 +1,88 @@
/*-
* Copyright (c) 2006,2008,2011 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <libelf.h>
#include <stdio.h>
#include <string.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_errmsg.c 1345 2011-01-01 11:17:52Z jkoshy $");
/*
* Retrieve a human readable translation for an error message.
*/
#if defined(__GNUC__)
#define DEFINE_ERROR(N,S) [ELF_E_##N] = S
#else
#define DEFINE_ERROR(N,S) S
#endif
const char *_libelf_errors[] = {
DEFINE_ERROR(NONE, "No Error"),
DEFINE_ERROR(ARCHIVE, "Malformed ar(1) archive"),
DEFINE_ERROR(ARGUMENT, "Invalid argument"),
DEFINE_ERROR(CLASS, "ELF class mismatch"),
DEFINE_ERROR(DATA, "Invalid data buffer descriptor"),
DEFINE_ERROR(HEADER, "Missing or malformed ELF header"),
DEFINE_ERROR(IO, "I/O error"),
DEFINE_ERROR(LAYOUT, "Layout constraint violation"),
DEFINE_ERROR(MODE, "Incorrect ELF descriptor mode"),
DEFINE_ERROR(RANGE, "Value out of range of target"),
DEFINE_ERROR(RESOURCE, "Resource exhaustion"),
DEFINE_ERROR(SECTION, "Invalid section descriptor"),
DEFINE_ERROR(SEQUENCE, "API calls out of sequence"),
DEFINE_ERROR(UNIMPL, "Unimplemented feature"),
DEFINE_ERROR(VERSION, "Unknown ELF API version"),
DEFINE_ERROR(NUM, "Unknown error")
};
#undef DEFINE_ERROR
const char *
elf_errmsg(int error)
{
int oserr;
if (error == ELF_E_NONE &&
(error = LIBELF_PRIVATE(error)) == 0)
return NULL;
else if (error == -1)
error = LIBELF_PRIVATE(error);
oserr = error >> LIBELF_OS_ERROR_SHIFT;
error &= LIBELF_ELF_ERROR_MASK;
if (error < ELF_E_NONE || error >= ELF_E_NUM)
return _libelf_errors[ELF_E_NUM];
if (oserr) {
(void) snprintf(LIBELF_PRIVATE(msg),
sizeof(LIBELF_PRIVATE(msg)), "%s: %s",
_libelf_errors[error], strerror(oserr));
return (const char *)&LIBELF_PRIVATE(msg);
}
return _libelf_errors[error];
}
+43
Переглянути файл
@@ -0,0 +1,43 @@
/*-
* Copyright (c) 2006,2008,2011 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_errno.c 1345 2011-01-01 11:17:52Z jkoshy $");
int
elf_errno(void)
{
int old;
old = LIBELF_PRIVATE(error);
LIBELF_PRIVATE(error) = 0;
return (old & LIBELF_ELF_ERROR_MASK);
}
+39
Переглянути файл
@@ -0,0 +1,39 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_fill.c 189 2008-07-20 10:38:08Z jkoshy $");
void
elf_fill(int fill)
{
LIBELF_PRIVATE(fillchar) = fill;
}
+195
Переглянути файл
@@ -0,0 +1,195 @@
/*-
* Copyright (c) 2006,2008-2009,2011 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_flag.c 1918 2011-09-22 10:42:06Z jkoshy $");
unsigned int
elf_flagarhdr(Elf_Arhdr *a, Elf_Cmd c, unsigned int flags)
{
unsigned int r;
if (a == NULL)
return (0);
if ((c != ELF_C_SET && c != ELF_C_CLR) ||
(flags & ~ELF_F_DIRTY) != 0) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if (c == ELF_C_SET)
r = a->ar_flags |= flags;
else
r = a->ar_flags &= ~flags;
return (r & LIBELF_F_API_MASK);
}
unsigned int
elf_flagdata(Elf_Data *d, Elf_Cmd c, unsigned int flags)
{
unsigned int r;
if (d == NULL)
return (0);
if ((c != ELF_C_SET && c != ELF_C_CLR) ||
(flags & ~ELF_F_DIRTY) != 0) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if (c == ELF_C_SET)
r = d->d_flags |= flags;
else
r = d->d_flags &= ~flags;
return (r & LIBELF_F_API_MASK);
}
unsigned int
elf_flagehdr(Elf *e, Elf_Cmd c, unsigned int flags)
{
int ec;
void *ehdr;
if (e == NULL)
return (0);
if ((c != ELF_C_SET && c != ELF_C_CLR) ||
(e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if (ec == ELFCLASS32)
ehdr = e->e_u.e_elf.e_ehdr.e_ehdr32;
else
ehdr = e->e_u.e_elf.e_ehdr.e_ehdr64;
if (ehdr == NULL) {
LIBELF_SET_ERROR(SEQUENCE, 0);
return (0);
}
return (elf_flagelf(e, c, flags));
}
unsigned int
elf_flagelf(Elf *e, Elf_Cmd c, unsigned int flags)
{
int r;
if (e == NULL)
return (0);
if ((c != ELF_C_SET && c != ELF_C_CLR) ||
(e->e_kind != ELF_K_ELF) ||
(flags & ~(ELF_F_ARCHIVE | ELF_F_ARCHIVE_SYSV |
ELF_F_DIRTY | ELF_F_LAYOUT)) != 0) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if ((flags & ELF_F_ARCHIVE_SYSV) && (flags & ELF_F_ARCHIVE) == 0) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if ((flags & ELF_F_ARCHIVE) && e->e_cmd != ELF_C_WRITE) {
LIBELF_SET_ERROR(MODE, 0);
return (0);
}
if (c == ELF_C_SET)
r = e->e_flags |= flags;
else
r = e->e_flags &= ~flags;
return (r & LIBELF_F_API_MASK);
}
unsigned int
elf_flagphdr(Elf *e, Elf_Cmd c, unsigned int flags)
{
int ec;
void *phdr;
if (e == NULL)
return (0);
if ((c != ELF_C_SET && c != ELF_C_CLR) ||
(e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if (ec == ELFCLASS32)
phdr = e->e_u.e_elf.e_phdr.e_phdr32;
else
phdr = e->e_u.e_elf.e_phdr.e_phdr64;
if (phdr == NULL) {
LIBELF_SET_ERROR(SEQUENCE, 0);
return (0);
}
return (elf_flagelf(e, c, flags));
}
unsigned int
elf_flagscn(Elf_Scn *s, Elf_Cmd c, unsigned int flags)
{
int r;
if (s == NULL)
return (0);
if ((c != ELF_C_SET && c != ELF_C_CLR) ||
(flags & ~ELF_F_DIRTY) != 0) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if (c == ELF_C_SET)
r = s->s_flags |= flags;
else
r = s->s_flags &= ~flags;
return (r & LIBELF_F_API_MASK);
}
unsigned int
elf_flagshdr(Elf_Scn *s, Elf_Cmd c, unsigned int flags)
{
return (elf_flagscn(s, c, flags));
}
+47
Переглянути файл
@@ -0,0 +1,47 @@
/*-
* Copyright (c) 2006,2008,2010 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_getarhdr.c 1341 2011-01-01 04:28:29Z jkoshy $");
Elf_Arhdr *
elf_getarhdr(Elf *e)
{
if (e == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if (e->e_flags & LIBELF_F_AR_HEADER)
return (e->e_hdr.e_arhdr);
return (_libelf_ar_gethdr(e));
}
+58
Переглянути файл
@@ -0,0 +1,58 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_getarsym.c 1360 2011-01-08 08:27:41Z jkoshy $");
Elf_Arsym *
elf_getarsym(Elf *ar, size_t *ptr)
{
size_t n;
Elf_Arsym *symtab;
n = 0;
symtab = NULL;
if (ar == NULL || ar->e_kind != ELF_K_AR)
LIBELF_SET_ERROR(ARGUMENT, 0);
else if ((symtab = ar->e_u.e_ar.e_symtab) != NULL)
n = ar->e_u.e_ar.e_symtabsz;
else if (ar->e_u.e_ar.e_rawsymtab)
symtab = (ar->e_flags & LIBELF_F_AR_VARIANT_SVR4) ?
_libelf_ar_process_svr4_symtab(ar, &n) :
_libelf_ar_process_bsd_symtab(ar, &n);
else
LIBELF_SET_ERROR(ARCHIVE, 0);
if (ptr)
*ptr = n;
return (symtab);
}
+48
Переглянути файл
@@ -0,0 +1,48 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_getbase.c 977 2010-06-06 11:50:31Z jkoshy $");
off_t
elf_getbase(Elf *e)
{
if (e == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return ((off_t) -1);
}
if (e->e_parent == NULL)
return ((off_t) 0);
return ((off_t) ((uintptr_t) e->e_rawfile -
(uintptr_t) e->e_parent->e_rawfile));
}
+68
Переглянути файл
@@ -0,0 +1,68 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <ar.h>
#include <assert.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_getident.c 189 2008-07-20 10:38:08Z jkoshy $");
char *
elf_getident(Elf *e, size_t *sz)
{
if (e == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
goto error;
}
if (e->e_cmd == ELF_C_WRITE && e->e_rawfile == NULL) {
LIBELF_SET_ERROR(SEQUENCE, 0);
goto error;
}
assert(e->e_kind != ELF_K_AR || e->e_cmd == ELF_C_READ);
if (sz) {
if (e->e_kind == ELF_K_AR)
*sz = SARMAG;
else if (e->e_kind == ELF_K_ELF)
*sz = EI_NIDENT;
else
*sz = e->e_rawsize;
}
return ((char *) e->e_rawfile);
error:
if (sz)
*sz = 0;
return (NULL);
}
+56
Переглянути файл
@@ -0,0 +1,56 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <libelf.h>
#include "_libelf_config.h"
LIBELF_VCSID("$Id: elf_hash.c 189 2008-07-20 10:38:08Z jkoshy $");
/*
* This elf_hash function is defined by the System V ABI.
*/
unsigned long
elf_hash(const char *name)
{
unsigned long h, t;
const unsigned char *s;
s = (const unsigned char *) name;
h = t = 0;
for (; *s != '\0'; h = h & ~t) {
h = (h << 4) + *s++;
t = h & 0xF0000000UL;
if (t)
h ^= t >> 24;
}
return (h);
}
+44
Переглянути файл
@@ -0,0 +1,44 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_kind.c 189 2008-07-20 10:38:08Z jkoshy $");
Elf_Kind
elf_kind(Elf *e)
{
if (e == NULL)
return (ELF_K_NONE);
if (e->e_kind == ELF_K_AR ||
e->e_kind == ELF_K_ELF)
return (e->e_kind);
return (ELF_K_NONE);
}
+92
Переглянути файл
@@ -0,0 +1,92 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <ar.h>
#include <libelf.h>
#include <string.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_memory.c 189 2008-07-20 10:38:08Z jkoshy $");
Elf *
elf_memory(char *image, size_t sz, Elf_Mem *mem)
{
Elf *e;
if (LIBELF_PRIVATE(version) == EV_NONE) {
LIBELF_SET_ERROR(SEQUENCE, 0);
return (NULL);
}
if (image == NULL || sz == 0) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if ((e = _libelf_allocate_elf(mem)) == NULL)
return (NULL);
e->e_cmd = ELF_C_READ;
e->e_rawfile = image;
e->e_rawsize = sz;
#undef LIBELF_IS_ELF
#define LIBELF_IS_ELF(P) ((P)[EI_MAG0] == ELFMAG0 && \
(P)[EI_MAG1] == ELFMAG1 && (P)[EI_MAG2] == ELFMAG2 && \
(P)[EI_MAG3] == ELFMAG3)
if (sz > EI_NIDENT && LIBELF_IS_ELF(image)) {
_libelf_init_elf(e, ELF_K_ELF);
e->e_class = image[EI_CLASS];
e->e_byteorder = image[EI_DATA];
e->e_version = image[EI_VERSION];
if (e->e_version > EV_CURRENT) {
e = _libelf_release_elf(e);
LIBELF_SET_ERROR(VERSION, 0);
return (NULL);
}
if ((e->e_byteorder != ELFDATA2LSB && e->e_byteorder !=
ELFDATA2MSB) || (e->e_class != ELFCLASS32 && e->e_class !=
ELFCLASS64)) {
e = _libelf_release_elf(e);
LIBELF_SET_ERROR(HEADER, 0);
return (NULL);
}
} else if (sz >= SARMAG &&
strncmp(image, ARMAG, (size_t) SARMAG) == 0) {
_libelf_init_elf(e, ELF_K_AR);
e = _libelf_ar_open(e);
} else
_libelf_init_elf(e, ELF_K_NONE);
return (e);
}
+62
Переглянути файл
@@ -0,0 +1,62 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <ar.h>
#include <assert.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_next.c 1678 2011-07-28 04:36:34Z jkoshy $");
Elf_Cmd
elf_next(Elf *e)
{
off_t next;
Elf *parent;
if (e == NULL)
return (ELF_C_NULL);
if ((parent = e->e_parent) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (ELF_C_NULL);
}
assert (parent->e_kind == ELF_K_AR);
assert (parent->e_cmd == ELF_C_READ);
assert(e->e_rawfile > parent->e_rawfile);
next = e->e_rawfile - parent->e_rawfile + e->e_rawsize;
next = (next + 1) & ~1; /* round up to an even boundary */
parent->e_u.e_ar.e_next = (next >= (off_t) parent->e_rawsize) ?
(off_t) 0 : next;
return (ELF_C_READ);
}
+67
Переглянути файл
@@ -0,0 +1,67 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <ar.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_phnum.c 466 2009-08-04 17:17:42Z jkoshy $");
static int
_libelf_getphdrnum(Elf *e, size_t *phnum)
{
void *eh;
int ec;
if (e == NULL || e->e_kind != ELF_K_ELF ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (-1);
}
if ((eh = _libelf_ehdr(e, ec, 0)) == NULL)
return (-1);
*phnum = e->e_u.e_elf.e_nphdr;
return (0);
}
int
elf_getphdrnum(Elf *e, size_t *phnum)
{
return (_libelf_getphdrnum(e, phnum));
}
/* Deprecated API */
int
elf_getphnum(Elf *e, size_t *phnum)
{
return (_libelf_getphdrnum(e, phnum) >= 0);
}
+59
Переглянути файл
@@ -0,0 +1,59 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <ar.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_rand.c 189 2008-07-20 10:38:08Z jkoshy $");
off_t
elf_rand(Elf *ar, off_t offset)
{
struct ar_hdr *arh;
if (ar == NULL || ar->e_kind != ELF_K_AR ||
(offset & 1) || offset < SARMAG ||
offset + sizeof(struct ar_hdr) >= ar->e_rawsize) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return 0;
}
arh = (struct ar_hdr *) (ar->e_rawfile + offset);
/* a too simple sanity check */
if (arh->ar_fmag[0] != '`' || arh->ar_fmag[1] != '\n') {
LIBELF_SET_ERROR(ARCHIVE, 0);
return 0;
}
ar->e_u.e_ar.e_next = offset;
return (offset);
}
+53
Переглянути файл
@@ -0,0 +1,53 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_rawfile.c 189 2008-07-20 10:38:08Z jkoshy $");
char *
elf_rawfile(Elf *e, size_t *sz)
{
char *ptr;
size_t size;
size = e ? e->e_rawsize : 0;
ptr = NULL;
if (e == NULL)
LIBELF_SET_ERROR(ARGUMENT, 0);
else if ((ptr = e->e_rawfile) == NULL && e->e_cmd == ELF_C_WRITE)
LIBELF_SET_ERROR(SEQUENCE, 0);
if (sz)
*sz = size;
return (ptr);
}
+245
Переглянути файл
@@ -0,0 +1,245 @@
/*-
* Copyright (c) 2006,2008-2010 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <sys/queue.h>
#include <assert.h>
#include <errno.h>
#include <gelf.h>
#include <libelf.h>
#include <stddef.h>
#include <stdlib.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_scn.c 1077 2010-08-09 15:37:40Z jkoshy $");
/*
* Load an ELF section table and create a list of Elf_Scn structures.
*/
int
_libelf_load_section_headers(Elf *e, void *ehdr)
{
int ec, swapbytes;
size_t fsz, i, shnum;
uint64_t shoff;
char *src;
Elf32_Ehdr *eh32;
Elf64_Ehdr *eh64;
Elf_Scn *scn;
int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap);
assert(e != NULL);
assert(ehdr != NULL);
assert((e->e_flags & LIBELF_F_SHDRS_LOADED) == 0);
#define CHECK_EHDR(E,EH) do { \
if (fsz != (EH)->e_shentsize || \
(e->e_rawfile && shoff + fsz * shnum > e->e_rawsize)) { \
LIBELF_SET_ERROR(HEADER, 0); \
return (0); \
} \
} while (0)
ec = e->e_class;
fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1);
assert(fsz > 0);
shnum = e->e_u.e_elf.e_nscn;
if (ec == ELFCLASS32) {
eh32 = (Elf32_Ehdr *) ehdr;
shoff = (uint64_t) eh32->e_shoff;
CHECK_EHDR(e, eh32);
} else {
eh64 = (Elf64_Ehdr *) ehdr;
shoff = eh64->e_shoff;
CHECK_EHDR(e, eh64);
}
xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec);
swapbytes = e->e_byteorder != LIBELF_PRIVATE(byteorder);
// If we aren't editing a rawfile, then we don't need to
// load any sections.
if (!e->e_rawfile) {
return 1;
}
src = e->e_rawfile + shoff;
/*
* If the file is using extended numbering then section #0
* would have already been read in.
*/
i = 0;
if (!STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) {
assert(STAILQ_FIRST(&e->e_u.e_elf.e_scn) ==
STAILQ_LAST(&e->e_u.e_elf.e_scn, _Elf_Scn, s_next));
i = 1;
src += fsz;
}
for (; i < shnum; i++, src += fsz) {
if ((scn = _libelf_allocate_scn(e, i)) == NULL)
return (0);
(*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr), src,
(size_t) 1, swapbytes);
if (ec == ELFCLASS32) {
scn->s_offset =
scn->s_shdr.s_shdr32.sh_offset;
scn->s_size = scn->s_shdr.s_shdr32.sh_size;
} else {
scn->s_offset =
scn->s_shdr.s_shdr64.sh_offset;
scn->s_size = scn->s_shdr.s_shdr64.sh_size;
}
// If we have a true read/write elf, we cannot trust the
// raw offset and we need to pull in the data also when
// the section headers are loaded.
if (e->e_cmd != ELF_C_RDWR) {
scn->s_rawoff = scn->s_offset;
} else {
elf_getdata(scn, NULL);
}
}
e->e_flags |= LIBELF_F_SHDRS_LOADED;
return (1);
}
Elf_Scn *
elf_getscn(Elf *e, size_t index)
{
int ec;
void *ehdr;
Elf_Scn *s;
if (e == NULL || e->e_kind != ELF_K_ELF ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
return (NULL);
if (e->e_cmd != ELF_C_WRITE &&
(e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 &&
_libelf_load_section_headers(e, ehdr) == 0)
return (NULL);
STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next)
if (s->s_ndx == index)
return (s);
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
size_t
elf_ndxscn(Elf_Scn *s)
{
if (s == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (SHN_UNDEF);
}
return (s->s_ndx);
}
Elf_Scn *
elf_newscn(Elf *e)
{
int ec;
void *ehdr;
Elf_Scn *scn;
if (e == NULL || e->e_kind != ELF_K_ELF) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) {
LIBELF_SET_ERROR(CLASS, 0);
return (NULL);
}
if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
return (NULL);
/*
* The application may be asking for a new section descriptor
* on an ELF object opened with ELF_C_RDWR or ELF_C_READ. We
* need to bring in the existing section information before
* appending a new one to the list.
*
* Per the ELF(3) API, an application is allowed to open a
* file using ELF_C_READ, mess with its internal structure and
* use elf_update(...,ELF_C_NULL) to compute its new layout.
*/
if (e->e_cmd != ELF_C_WRITE &&
(e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 &&
_libelf_load_section_headers(e, ehdr) == 0)
return (NULL);
if (STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) {
assert(e->e_u.e_elf.e_nscn == 0);
if ((scn = _libelf_allocate_scn(e, (size_t) SHN_UNDEF)) ==
NULL)
return (NULL);
e->e_u.e_elf.e_nscn++;
}
assert(e->e_u.e_elf.e_nscn > 0);
if ((scn = _libelf_allocate_scn(e, e->e_u.e_elf.e_nscn)) == NULL)
return (NULL);
e->e_u.e_elf.e_nscn++;
(void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY);
return (scn);
}
Elf_Scn *
elf_nextscn(Elf *e, Elf_Scn *s)
{
if (e == NULL || (e->e_kind != ELF_K_ELF) ||
(s && s->s_elf != e)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
return (s == NULL ? elf_getscn(e, (size_t) 1) :
STAILQ_NEXT(s, s_next));
}
+67
Переглянути файл
@@ -0,0 +1,67 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <ar.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_shnum.c 466 2009-08-04 17:17:42Z jkoshy $");
static int
_libelf_getshdrnum(Elf *e, size_t *shnum)
{
void *eh;
int ec;
if (e == NULL || e->e_kind != ELF_K_ELF ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (-1);
}
if ((eh = _libelf_ehdr(e, ec, 0)) == NULL)
return (-1);
*shnum = e->e_u.e_elf.e_nscn;
return (0);
}
int
elf_getshdrnum(Elf *e, size_t *shnum)
{
return (_libelf_getshdrnum(e, shnum));
}
/* Deprecated API. */
int
elf_getshnum(Elf *e, size_t *shnum)
{
return (_libelf_getshdrnum(e, shnum) >= 0);
}
+82
Переглянути файл
@@ -0,0 +1,82 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <ar.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_shstrndx.c 466 2009-08-04 17:17:42Z jkoshy $");
static int
_libelf_getshdrstrndx(Elf *e, size_t *strndx)
{
void *eh;
int ec;
if (e == NULL || e->e_kind != ELF_K_ELF ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (-1);
}
if ((eh = _libelf_ehdr(e, ec, 0)) == NULL)
return (-1);
*strndx = e->e_u.e_elf.e_strndx;
return (0);
}
int
elf_getshdrstrndx(Elf *e, size_t *strndx)
{
return (_libelf_getshdrstrndx(e, strndx));
}
int
elf_getshstrndx(Elf *e, size_t *strndx) /* Deprecated API. */
{
return (_libelf_getshdrstrndx(e, strndx) >= 0);
}
int
elf_setshstrndx(Elf *e, size_t strndx)
{
void *eh;
int ec;
if (e == NULL || e->e_kind != ELF_K_ELF ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) ||
((eh = _libelf_ehdr(e, ec, 0)) == NULL)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
return (_libelf_setshstrndx(e, eh, ec, strndx));
}
+136
Переглянути файл
@@ -0,0 +1,136 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <assert.h>
#include <gelf.h>
#include "_libelf.h"
#ifdef ANDROID
#include "roundup.h"
#else
#include <sys/param.h>
#endif
LIBELF_VCSID("$Id: elf_strptr.c 189 2008-07-20 10:38:08Z jkoshy $");
/*
* Convert an ELF section#,offset pair to a string pointer.
*/
char *
elf_strptr(Elf *e, size_t scndx, size_t offset)
{
Elf_Scn *s;
Elf_Data *d;
size_t alignment, count;
GElf_Shdr shdr;
if (e == NULL || e->e_kind != ELF_K_ELF) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if ((s = elf_getscn(e, scndx)) == NULL ||
gelf_getshdr(s, &shdr) == NULL)
return (NULL);
if (shdr.sh_type != SHT_STRTAB ||
offset >= shdr.sh_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
d = NULL;
if (e->e_flags & ELF_F_LAYOUT) {
/*
* The application is taking responsibility for the
* ELF object's layout, so we can directly translate
* an offset to a `char *' address using the `d_off'
* members of Elf_Data descriptors.
*/
while ((d = elf_getdata(s, d)) != NULL) {
if (d->d_buf == 0 || d->d_size == 0)
continue;
if (d->d_type != ELF_T_BYTE) {
LIBELF_SET_ERROR(DATA, 0);
return (NULL);
}
if (offset >= d->d_off &&
offset < d->d_off + d->d_size)
return ((char *) d->d_buf + offset - d->d_off);
}
} else {
/*
* Otherwise, the `d_off' members are not useable and
* we need to compute offsets ourselves, taking into
* account 'holes' in coverage of the section introduced
* by alignment requirements.
*/
count = (size_t) 0; /* cumulative count of bytes seen */
while ((d = elf_getdata(s, d)) != NULL && count <= offset) {
if (d->d_buf == NULL || d->d_size == 0)
continue;
if (d->d_type != ELF_T_BYTE) {
LIBELF_SET_ERROR(DATA, 0);
return (NULL);
}
if ((alignment = d->d_align) > 1) {
if ((alignment & (alignment - 1)) != 0) {
LIBELF_SET_ERROR(DATA, 0);
return (NULL);
}
count = roundup2(count, alignment);
}
if (offset < count) {
/* offset starts in the 'hole' */
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if (offset < count + d->d_size) {
if (d->d_buf != NULL)
return ((char *) d->d_buf +
offset - count);
LIBELF_SET_ERROR(DATA, 0);
return (NULL);
}
count += d->d_size;
}
}
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
Різницю між файлами не показано, бо вона завелика Завантажити різницю
+52
Переглянути файл
@@ -0,0 +1,52 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: elf_version.c 189 2008-07-20 10:38:08Z jkoshy $");
unsigned int
elf_version(unsigned int v)
{
unsigned int old;
if ((old = LIBELF_PRIVATE(version)) == EV_NONE)
old = EV_CURRENT;
if (v == EV_NONE)
return old;
if (v > EV_CURRENT) {
LIBELF_SET_ERROR(VERSION, 0);
return EV_NONE;
}
LIBELF_PRIVATE(version) = v;
return (old);
}
+114
Переглянути файл
@@ -0,0 +1,114 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: gelf.h 1168 2010-09-04 01:03:25Z jkoshy $
*/
#ifndef _GELF_H_
#define _GELF_H_
#include <sys/cdefs.h>
#include <libelf.h>
typedef Elf64_Addr GElf_Addr; /* Addresses */
typedef Elf64_Half GElf_Half; /* Half words (16 bit) */
typedef Elf64_Off GElf_Off; /* Offsets */
typedef Elf64_Sword GElf_Sword; /* Signed words (32 bit) */
typedef Elf64_Sxword GElf_Sxword; /* Signed long words (64 bit) */
typedef Elf64_Word GElf_Word; /* Unsigned words (32 bit) */
typedef Elf64_Xword GElf_Xword; /* Unsigned long words (64 bit) */
typedef Elf64_Dyn GElf_Dyn; /* ".dynamic" section entries */
typedef Elf64_Ehdr GElf_Ehdr; /* ELF header */
typedef Elf64_Phdr GElf_Phdr; /* Program header */
typedef Elf64_Shdr GElf_Shdr; /* Section header */
typedef Elf64_Sym GElf_Sym; /* Symbol table entries */
typedef Elf64_Rel GElf_Rel; /* Relocation entries */
typedef Elf64_Rela GElf_Rela; /* Relocation entries with addend */
#if (defined(__FreeBSD_version) && __FreeBSD_version >= 700025) || \
(defined(__NetBSD_Version) && __NetBSD_Version > 400000003)
typedef Elf64_Cap GElf_Cap; /* SW/HW capabilities */
typedef Elf64_Move GElf_Move; /* Move entries */
typedef Elf64_Syminfo GElf_Syminfo; /* Symbol information */
#endif
#define GELF_M_INFO ELF64_M_INFO
#define GELF_M_SIZE ELF64_M_SIZE
#define GELF_M_SYM ELF64_M_SYM
#define GELF_R_INFO ELF64_R_INFO
#define GELF_R_SYM ELF64_R_SYM
#define GELF_R_TYPE ELF64_R_TYPE
#define GELF_R_TYPE_DATA ELF64_R_TYPE_DATA
#define GELF_R_TYPE_ID ELF64_R_TYPE_ID
#define GELF_R_TYPE_INFO ELF64_R_TYPE_INFO
#define GELF_ST_BIND ELF64_ST_BIND
#define GELF_ST_INFO ELF64_ST_INFO
#define GELF_ST_TYPE ELF64_ST_TYPE
#define GELF_ST_VISIBILITY ELF64_ST_VISIBILITY
__BEGIN_DECLS
long gelf_checksum(Elf *_elf);
size_t gelf_fsize(Elf *_elf, Elf_Type _type, size_t _count,
unsigned int _version);
int gelf_getclass(Elf *_elf);
GElf_Dyn *gelf_getdyn(Elf_Data *_data, int _index, GElf_Dyn *_dst);
GElf_Ehdr *gelf_getehdr(Elf *_elf, GElf_Ehdr *_dst);
GElf_Phdr *gelf_getphdr(Elf *_elf, int _index, GElf_Phdr *_dst);
GElf_Rel *gelf_getrel(Elf_Data *_src, int _index, GElf_Rel *_dst);
GElf_Rela *gelf_getrela(Elf_Data *_src, int _index, GElf_Rela *_dst);
GElf_Shdr *gelf_getshdr(Elf_Scn *_scn, GElf_Shdr *_dst);
GElf_Sym *gelf_getsym(Elf_Data *_src, int _index, GElf_Sym *_dst);
GElf_Sym *gelf_getsymshndx(Elf_Data *_src, Elf_Data *_shindexsrc,
int _index, GElf_Sym *_dst, Elf32_Word *_shindexdst);
void * gelf_newehdr(Elf *_elf, int _class);
void * gelf_newphdr(Elf *_elf, size_t _phnum);
int gelf_update_dyn(Elf_Data *_dst, int _index, GElf_Dyn *_src);
int gelf_update_ehdr(Elf *_elf, GElf_Ehdr *_src);
int gelf_update_phdr(Elf *_elf, int _index, GElf_Phdr *_src);
int gelf_update_rel(Elf_Data *_dst, int _index, GElf_Rel *_src);
int gelf_update_rela(Elf_Data *_dst, int _index, GElf_Rela *_src);
int gelf_update_shdr(Elf_Scn *_dst, GElf_Shdr *_src);
int gelf_update_sym(Elf_Data *_dst, int _index, GElf_Sym *_src);
int gelf_update_symshndx(Elf_Data *_symdst, Elf_Data *_shindexdst,
int _index, GElf_Sym *_symsrc, Elf32_Word _shindexsrc);
Elf_Data *gelf_xlatetof(Elf *_elf, Elf_Data *_dst, const Elf_Data *_src, unsigned int _encode);
Elf_Data *gelf_xlatetom(Elf *_elf, Elf_Data *_dst, const Elf_Data *_src, unsigned int _encode);
#if (defined(__FreeBSD_version) && __FreeBSD_version >= 700025) || \
(defined(__NetBSD_Version) && __NetBSD_Version > 400000003)
GElf_Cap *gelf_getcap(Elf_Data *_data, int _index, GElf_Cap *_cap);
GElf_Move *gelf_getmove(Elf_Data *_src, int _index, GElf_Move *_dst);
GElf_Syminfo *gelf_getsyminfo(Elf_Data *_src, int _index, GElf_Syminfo *_dst);
int gelf_update_cap(Elf_Data *_dst, int _index, GElf_Cap *_src);
int gelf_update_move(Elf_Data *_dst, int _index, GElf_Move *_src);
int gelf_update_syminfo(Elf_Data *_dst, int _index, GElf_Syminfo *_src);
#endif
__END_DECLS
#endif /* _GELF_H_ */
+148
Переглянути файл
@@ -0,0 +1,148 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <gelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: gelf_cap.c 1166 2010-09-04 00:54:36Z jkoshy $");
#if LIBELF_CONFIG_CAP
GElf_Cap *
gelf_getcap(Elf_Data *d, int ndx, GElf_Cap *dst)
{
int ec;
Elf *e;
Elf_Scn *scn;
Elf32_Cap *cap32;
Elf64_Cap *cap64;
size_t msz;
uint32_t sh_type;
if (d == NULL || ndx < 0 || dst == NULL ||
(scn = d->d_scn) == NULL ||
(e = scn->s_elf) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
ec = e->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32)
sh_type = scn->s_shdr.s_shdr32.sh_type;
else
sh_type = scn->s_shdr.s_shdr64.sh_type;
if (_libelf_xlate_shtype(sh_type) != ELF_T_CAP) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
msz = _libelf_msize(ELF_T_CAP, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if (ec == ELFCLASS32) {
cap32 = (Elf32_Cap *) d->d_buf + ndx;
dst->c_tag = cap32->c_tag;
dst->c_un.c_val = (Elf64_Xword) cap32->c_un.c_val;
} else {
cap64 = (Elf64_Cap *) d->d_buf + ndx;
*dst = *cap64;
}
return (dst);
}
int
gelf_update_cap(Elf_Data *d, int ndx, GElf_Cap *gc)
{
int ec;
Elf *e;
Elf_Scn *scn;
Elf32_Cap *cap32;
Elf64_Cap *cap64;
size_t msz;
uint32_t sh_type;
if (d == NULL || ndx < 0 || gc == NULL ||
(scn = d->d_scn) == NULL ||
(e = scn->s_elf) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
ec = e->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32)
sh_type = scn->s_shdr.s_shdr32.sh_type;
else
sh_type = scn->s_shdr.s_shdr64.sh_type;
if (_libelf_xlate_shtype(sh_type) != ELF_T_CAP) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
msz = _libelf_msize(ELF_T_CAP, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if (ec == ELFCLASS32) {
cap32 = (Elf32_Cap *) d->d_buf + ndx;
LIBELF_COPY_U32(cap32, gc, c_tag);
LIBELF_COPY_U32(cap32, gc, c_un.c_val);
} else {
cap64 = (Elf64_Cap *) d->d_buf + ndx;
*cap64 = *gc;
}
return (1);
}
#endif /* LIBELF_CONFIG_CAP */
+58
Переглянути файл
@@ -0,0 +1,58 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <gelf.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: gelf_checksum.c 189 2008-07-20 10:38:08Z jkoshy $");
long
elf32_checksum(Elf *e)
{
return (_libelf_checksum(e, ELFCLASS32));
}
long
elf64_checksum(Elf *e)
{
return (_libelf_checksum(e, ELFCLASS64));
}
long
gelf_checksum(Elf *e)
{
int ec;
if (e == NULL ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0L);
}
return (_libelf_checksum(e, ec));
}
+143
Переглянути файл
@@ -0,0 +1,143 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <gelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: gelf_dyn.c 189 2008-07-20 10:38:08Z jkoshy $");
GElf_Dyn *
gelf_getdyn(Elf_Data *d, int ndx, GElf_Dyn *dst)
{
int ec;
Elf *e;
Elf_Scn *scn;
Elf32_Dyn *dyn32;
Elf64_Dyn *dyn64;
size_t msz;
uint32_t sh_type;
if (d == NULL || ndx < 0 || dst == NULL ||
(scn = d->d_scn) == NULL ||
(e = scn->s_elf) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
ec = e->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32)
sh_type = scn->s_shdr.s_shdr32.sh_type;
else
sh_type = scn->s_shdr.s_shdr64.sh_type;
if (_libelf_xlate_shtype(sh_type) != ELF_T_DYN) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
msz = _libelf_msize(ELF_T_DYN, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if (ec == ELFCLASS32) {
dyn32 = (Elf32_Dyn *) d->d_buf + ndx;
dst->d_tag = dyn32->d_tag;
dst->d_un.d_val = (Elf64_Xword) dyn32->d_un.d_val;
} else {
dyn64 = (Elf64_Dyn *) d->d_buf + ndx;
*dst = *dyn64;
}
return (dst);
}
int
gelf_update_dyn(Elf_Data *d, int ndx, GElf_Dyn *ds)
{
int ec;
Elf *e;
Elf_Scn *scn;
Elf32_Dyn *dyn32;
Elf64_Dyn *dyn64;
size_t msz;
uint32_t sh_type;
if (d == NULL || ndx < 0 || ds == NULL ||
(scn = d->d_scn) == NULL ||
(e = scn->s_elf) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
ec = e->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32)
sh_type = scn->s_shdr.s_shdr32.sh_type;
else
sh_type = scn->s_shdr.s_shdr64.sh_type;
if (_libelf_xlate_shtype(sh_type) != ELF_T_DYN) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
msz = _libelf_msize(ELF_T_DYN, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if (ec == ELFCLASS32) {
dyn32 = (Elf32_Dyn *) d->d_buf + ndx;
LIBELF_COPY_S32(dyn32, ds, d_tag);
LIBELF_COPY_U32(dyn32, ds, d_un.d_val);
} else {
dyn64 = (Elf64_Dyn *) d->d_buf + ndx;
*dyn64 = *ds;
}
return (1);
}
+167
Переглянути файл
@@ -0,0 +1,167 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <gelf.h>
#include <libelf.h>
#include <string.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: gelf_ehdr.c 1678 2011-07-28 04:36:34Z jkoshy $");
Elf32_Ehdr *
elf32_getehdr(Elf *e)
{
return (_libelf_ehdr(e, ELFCLASS32, 0));
}
Elf64_Ehdr *
elf64_getehdr(Elf *e)
{
return (_libelf_ehdr(e, ELFCLASS64, 0));
}
GElf_Ehdr *
gelf_getehdr(Elf *e, GElf_Ehdr *d)
{
int ec;
Elf32_Ehdr *eh32;
Elf64_Ehdr *eh64;
if (d == NULL || e == NULL ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if (ec == ELFCLASS32) {
if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL)
return (NULL);
(void) memcpy(d->e_ident, eh32->e_ident,
sizeof(eh32->e_ident));
d->e_type = eh32->e_type;
d->e_machine = eh32->e_machine;
d->e_version = eh32->e_version;
d->e_entry = eh32->e_entry;
d->e_phoff = eh32->e_phoff;
d->e_shoff = eh32->e_shoff;
d->e_flags = eh32->e_flags;
d->e_ehsize = eh32->e_ehsize;
d->e_phentsize = eh32->e_phentsize;
d->e_phnum = eh32->e_phnum;
d->e_shentsize = eh32->e_shentsize;
d->e_shnum = eh32->e_shnum;
d->e_shstrndx = eh32->e_shstrndx;
return (d);
}
assert(ec == ELFCLASS64);
if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL)
return (NULL);
*d = *eh64;
return (d);
}
Elf32_Ehdr *
elf32_newehdr(Elf *e)
{
return (_libelf_ehdr(e, ELFCLASS32, 1));
}
Elf64_Ehdr *
elf64_newehdr(Elf *e)
{
return (_libelf_ehdr(e, ELFCLASS64, 1));
}
void *
gelf_newehdr(Elf *e, int ec)
{
if (e != NULL &&
(ec == ELFCLASS32 || ec == ELFCLASS64))
return (_libelf_ehdr(e, ec, 1));
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
int
gelf_update_ehdr(Elf *e, GElf_Ehdr *s)
{
int ec;
void *ehdr;
Elf32_Ehdr *eh32;
Elf64_Ehdr *eh64;
if (s== NULL || e == NULL || e->e_kind != ELF_K_ELF ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if (e->e_cmd == ELF_C_READ) {
LIBELF_SET_ERROR(MODE, 0);
return (0);
}
if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
return (0);
(void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY);
if (ec == ELFCLASS64) {
eh64 = (Elf64_Ehdr *) ehdr;
*eh64 = *s;
return (1);
}
eh32 = (Elf32_Ehdr *) ehdr;
(void) memcpy(eh32->e_ident, s->e_ident, sizeof(eh32->e_ident));
eh32->e_type = s->e_type;
eh32->e_machine = s->e_machine;
eh32->e_version = s->e_version;
LIBELF_COPY_U32(eh32, s, e_entry);
LIBELF_COPY_U32(eh32, s, e_phoff);
LIBELF_COPY_U32(eh32, s, e_shoff);
eh32->e_flags = s->e_flags;
eh32->e_ehsize = s->e_ehsize;
eh32->e_phentsize = s->e_phentsize;
eh32->e_phnum = s->e_phnum;
eh32->e_shentsize = s->e_shentsize;
eh32->e_shnum = s->e_shnum;
eh32->e_shstrndx = s->e_shstrndx;
return (1);
}
+62
Переглянути файл
@@ -0,0 +1,62 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <gelf.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: gelf_fsize.c 189 2008-07-20 10:38:08Z jkoshy $");
size_t
elf32_fsize(Elf_Type t, size_t c, unsigned int v)
{
return (_libelf_fsize(t, ELFCLASS32, v, c));
}
size_t
elf64_fsize(Elf_Type t, size_t c, unsigned int v)
{
return (_libelf_fsize(t, ELFCLASS64, v, c));
}
size_t
gelf_fsize(Elf *e, Elf_Type t, size_t c, unsigned int v)
{
if (e == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if (e->e_class == ELFCLASS32 || e->e_class == ELFCLASS64)
return (_libelf_fsize(t, e->e_class, v, c));
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
+39
Переглянути файл
@@ -0,0 +1,39 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <gelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: gelf_getclass.c 189 2008-07-20 10:38:08Z jkoshy $");
int
gelf_getclass(Elf *e)
{
return (e != NULL ? e->e_class : ELFCLASSNONE);
}
+154
Переглянути файл
@@ -0,0 +1,154 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <gelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: gelf_move.c 1166 2010-09-04 00:54:36Z jkoshy $");
#if LIBELF_CONFIG_MOVE
GElf_Move *
gelf_getmove(Elf_Data *d, int ndx, GElf_Move *dst)
{
int ec;
Elf *e;
Elf_Scn *scn;
Elf32_Move *move32;
Elf64_Move *move64;
size_t msz;
uint32_t sh_type;
if (d == NULL || ndx < 0 || dst == NULL ||
(scn = d->d_scn) == NULL ||
(e = scn->s_elf) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
ec = e->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32)
sh_type = scn->s_shdr.s_shdr32.sh_type;
else
sh_type = scn->s_shdr.s_shdr64.sh_type;
if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if (ec == ELFCLASS32) {
move32 = (Elf32_Move *) d->d_buf + ndx;
dst->m_value = move32->m_value;
dst->m_info = (Elf64_Xword) move32->m_info;
dst->m_poffset = (Elf64_Xword) move32->m_poffset;
dst->m_repeat = move32->m_repeat;
dst->m_stride = move32->m_stride;
} else {
move64 = (Elf64_Move *) d->d_buf + ndx;
*dst = *move64;
}
return (dst);
}
int
gelf_update_move(Elf_Data *d, int ndx, GElf_Move *gm)
{
int ec;
Elf *e;
Elf_Scn *scn;
Elf32_Move *move32;
Elf64_Move *move64;
size_t msz;
uint32_t sh_type;
if (d == NULL || ndx < 0 || gm == NULL ||
(scn = d->d_scn) == NULL ||
(e = scn->s_elf) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
ec = e->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32)
sh_type = scn->s_shdr.s_shdr32.sh_type;
else
sh_type = scn->s_shdr.s_shdr64.sh_type;
if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if (ec == ELFCLASS32) {
move32 = (Elf32_Move *) d->d_buf + ndx;
move32->m_value = gm->m_value;
LIBELF_COPY_U32(move32, gm, m_info);
LIBELF_COPY_U32(move32, gm, m_poffset);
move32->m_repeat = gm->m_repeat;
move32->m_stride = gm->m_stride;
} else {
move64 = (Elf64_Move *) d->d_buf + ndx;
*move64 = *gm;
}
return (1);
}
#endif /* LIBELF_CONFIG_MOVE */
+177
Переглянути файл
@@ -0,0 +1,177 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <gelf.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: gelf_phdr.c 189 2008-07-20 10:38:08Z jkoshy $");
Elf32_Phdr *
elf32_getphdr(Elf *e)
{
return (_libelf_getphdr(e, ELFCLASS32));
}
Elf64_Phdr *
elf64_getphdr(Elf *e)
{
return (_libelf_getphdr(e, ELFCLASS64));
}
GElf_Phdr *
gelf_getphdr(Elf *e, int index, GElf_Phdr *d)
{
int ec;
Elf32_Ehdr *eh32;
Elf64_Ehdr *eh64;
Elf32_Phdr *ep32;
Elf64_Phdr *ep64;
if (d == NULL || e == NULL ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) ||
(e->e_kind != ELF_K_ELF) || index < 0) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if (ec == ELFCLASS32) {
if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL ||
((ep32 = _libelf_getphdr(e, ELFCLASS32)) == NULL))
return (NULL);
if (index >= eh32->e_phnum) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
ep32 += index;
d->p_type = ep32->p_type;
d->p_offset = ep32->p_offset;
d->p_vaddr = (Elf64_Addr) ep32->p_vaddr;
d->p_paddr = (Elf64_Addr) ep32->p_paddr;
d->p_filesz = (Elf64_Xword) ep32->p_filesz;
d->p_memsz = (Elf64_Xword) ep32->p_memsz;
d->p_flags = ep32->p_flags;
d->p_align = (Elf64_Xword) ep32->p_align;
} else {
if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL ||
(ep64 = _libelf_getphdr(e, ELFCLASS64)) == NULL)
return (NULL);
if (index >= eh64->e_phnum) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
ep64 += index;
*d = *ep64;
}
return (d);
}
Elf32_Phdr *
elf32_newphdr(Elf *e, size_t count)
{
return (_libelf_newphdr(e, ELFCLASS32, count));
}
Elf64_Phdr *
elf64_newphdr(Elf *e, size_t count)
{
return (_libelf_newphdr(e, ELFCLASS64, count));
}
void *
gelf_newphdr(Elf *e, size_t count)
{
if (e == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
return (_libelf_newphdr(e, e->e_class, count));
}
int
gelf_update_phdr(Elf *e, int ndx, GElf_Phdr *s)
{
int ec, phnum;
void *ehdr;
Elf32_Phdr *ph32;
Elf64_Phdr *ph64;
if (s == NULL || e == NULL || e->e_kind != ELF_K_ELF ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if (e->e_cmd == ELF_C_READ) {
LIBELF_SET_ERROR(MODE, 0);
return (0);
}
if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
return (0);
if (ec == ELFCLASS32)
phnum = ((Elf32_Ehdr *) ehdr)->e_phnum;
else
phnum = ((Elf64_Ehdr *) ehdr)->e_phnum;
if (ndx < 0 || ndx > phnum) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
(void) elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY);
if (ec == ELFCLASS64) {
ph64 = e->e_u.e_elf.e_phdr.e_phdr64 + ndx;
*ph64 = *s;
return (1);
}
ph32 = e->e_u.e_elf.e_phdr.e_phdr32 + ndx;
ph32->p_type = s->p_type;
ph32->p_flags = s->p_flags;
LIBELF_COPY_U32(ph32, s, p_offset);
LIBELF_COPY_U32(ph32, s, p_vaddr);
LIBELF_COPY_U32(ph32, s, p_paddr);
LIBELF_COPY_U32(ph32, s, p_filesz);
LIBELF_COPY_U32(ph32, s, p_memsz);
LIBELF_COPY_U32(ph32, s, p_align);
return (1);
}
+152
Переглянути файл
@@ -0,0 +1,152 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <gelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: gelf_rel.c 189 2008-07-20 10:38:08Z jkoshy $");
GElf_Rel *
gelf_getrel(Elf_Data *d, int ndx, GElf_Rel *dst)
{
int ec;
Elf *e;
Elf_Scn *scn;
Elf32_Rel *rel32;
Elf64_Rel *rel64;
size_t msz;
uint32_t sh_type;
if (d == NULL || ndx < 0 || dst == NULL ||
(scn = d->d_scn) == NULL ||
(e = scn->s_elf) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
ec = e->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32)
sh_type = scn->s_shdr.s_shdr32.sh_type;
else
sh_type = scn->s_shdr.s_shdr64.sh_type;
if (_libelf_xlate_shtype(sh_type) != ELF_T_REL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
msz = _libelf_msize(ELF_T_REL, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if (ec == ELFCLASS32) {
rel32 = (Elf32_Rel *) d->d_buf + ndx;
dst->r_offset = (Elf64_Addr) rel32->r_offset;
dst->r_info = ELF64_R_INFO(
(Elf64_Xword) ELF32_R_SYM(rel32->r_info),
ELF32_R_TYPE(rel32->r_info));
} else {
rel64 = (Elf64_Rel *) d->d_buf + ndx;
*dst = *rel64;
}
return (dst);
}
int
gelf_update_rel(Elf_Data *d, int ndx, GElf_Rel *dr)
{
int ec;
Elf *e;
Elf_Scn *scn;
Elf32_Rel *rel32;
Elf64_Rel *rel64;
size_t msz;
uint32_t sh_type;
if (d == NULL || ndx < 0 || dr == NULL ||
(scn = d->d_scn) == NULL ||
(e = scn->s_elf) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
ec = e->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32)
sh_type = scn->s_shdr.s_shdr32.sh_type;
else
sh_type = scn->s_shdr.s_shdr64.sh_type;
if (_libelf_xlate_shtype(sh_type) != ELF_T_REL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
msz = _libelf_msize(ELF_T_REL, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if (ec == ELFCLASS32) {
rel32 = (Elf32_Rel *) d->d_buf + ndx;
LIBELF_COPY_U32(rel32, dr, r_offset);
if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) ||
ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) {
LIBELF_SET_ERROR(RANGE, 0);
return (0);
}
rel32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info),
ELF64_R_TYPE(dr->r_info));
} else {
rel64 = (Elf64_Rel *) d->d_buf + ndx;
*rel64 = *dr;
}
return (1);
}
+155
Переглянути файл
@@ -0,0 +1,155 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <gelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: gelf_rela.c 189 2008-07-20 10:38:08Z jkoshy $");
GElf_Rela *
gelf_getrela(Elf_Data *d, int ndx, GElf_Rela *dst)
{
int ec;
Elf *e;
Elf_Scn *scn;
Elf32_Rela *rela32;
Elf64_Rela *rela64;
size_t msz;
uint32_t sh_type;
if (d == NULL || ndx < 0 || dst == NULL ||
(scn = d->d_scn) == NULL ||
(e = scn->s_elf) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
ec = e->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32)
sh_type = scn->s_shdr.s_shdr32.sh_type;
else
sh_type = scn->s_shdr.s_shdr64.sh_type;
if (_libelf_xlate_shtype(sh_type) != ELF_T_RELA) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
msz = _libelf_msize(ELF_T_RELA, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if (ec == ELFCLASS32) {
rela32 = (Elf32_Rela *) d->d_buf + ndx;
dst->r_offset = (Elf64_Addr) rela32->r_offset;
dst->r_info = ELF64_R_INFO(
(Elf64_Xword) ELF32_R_SYM(rela32->r_info),
ELF32_R_TYPE(rela32->r_info));
dst->r_addend = (Elf64_Sxword) rela32->r_addend;
} else {
rela64 = (Elf64_Rela *) d->d_buf + ndx;
*dst = *rela64;
}
return (dst);
}
int
gelf_update_rela(Elf_Data *d, int ndx, GElf_Rela *dr)
{
int ec;
Elf *e;
Elf_Scn *scn;
Elf32_Rela *rela32;
Elf64_Rela *rela64;
size_t msz;
uint32_t sh_type;
if (d == NULL || ndx < 0 || dr == NULL ||
(scn = d->d_scn) == NULL ||
(e = scn->s_elf) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
ec = e->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32)
sh_type = scn->s_shdr.s_shdr32.sh_type;
else
sh_type = scn->s_shdr.s_shdr64.sh_type;
if (_libelf_xlate_shtype(sh_type) != ELF_T_RELA) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
msz = _libelf_msize(ELF_T_RELA, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if (ec == ELFCLASS32) {
rela32 = (Elf32_Rela *) d->d_buf + ndx;
LIBELF_COPY_U32(rela32, dr, r_offset);
if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) ||
ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) {
LIBELF_SET_ERROR(RANGE, 0);
return (0);
}
rela32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info),
ELF64_R_TYPE(dr->r_info));
LIBELF_COPY_S32(rela32, dr, r_addend);
} else {
rela64 = (Elf64_Rela *) d->d_buf + ndx;
*rela64 = *dr;
}
return (1);
}
+129
Переглянути файл
@@ -0,0 +1,129 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <gelf.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: gelf_shdr.c 189 2008-07-20 10:38:08Z jkoshy $");
Elf32_Shdr *
elf32_getshdr(Elf_Scn *s)
{
return (_libelf_getshdr(s, ELFCLASS32));
}
Elf64_Shdr *
elf64_getshdr(Elf_Scn *s)
{
return (_libelf_getshdr(s, ELFCLASS64));
}
GElf_Shdr *
gelf_getshdr(Elf_Scn *s, GElf_Shdr *d)
{
int ec;
void *sh;
Elf32_Shdr *sh32;
Elf64_Shdr *sh64;
if (d == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if ((sh = _libelf_getshdr(s, ELFCLASSNONE)) == NULL)
return (NULL);
ec = s->s_elf->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32) {
sh32 = (Elf32_Shdr *) sh;
d->sh_name = sh32->sh_name;
d->sh_type = sh32->sh_type;
d->sh_flags = (Elf64_Xword) sh32->sh_flags;
d->sh_addr = (Elf64_Addr) sh32->sh_addr;
d->sh_offset = (Elf64_Off) sh32->sh_offset;
d->sh_size = (Elf64_Xword) sh32->sh_size;
d->sh_link = sh32->sh_link;
d->sh_info = sh32->sh_info;
d->sh_addralign = (Elf64_Xword) sh32->sh_addralign;
d->sh_entsize = (Elf64_Xword) sh32->sh_entsize;
} else {
sh64 = (Elf64_Shdr *) sh;
*d = *sh64;
}
return (d);
}
int
gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *s)
{
int ec;
Elf *e;
Elf32_Shdr *sh32;
if (s == NULL || scn == NULL || (e = scn->s_elf) == NULL ||
e->e_kind != ELF_K_ELF ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if (e->e_cmd == ELF_C_READ) {
LIBELF_SET_ERROR(MODE, 0);
return (0);
}
(void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY);
if (ec == ELFCLASS64) {
scn->s_shdr.s_shdr64 = *s;
return (1);
}
sh32 = &scn->s_shdr.s_shdr32;
sh32->sh_name = s->sh_name;
sh32->sh_type = s->sh_type;
LIBELF_COPY_U32(sh32, s, sh_flags);
LIBELF_COPY_U32(sh32, s, sh_addr);
LIBELF_COPY_U32(sh32, s, sh_offset);
LIBELF_COPY_U32(sh32, s, sh_size);
sh32->sh_link = s->sh_link;
sh32->sh_info = s->sh_info;
LIBELF_COPY_U32(sh32, s, sh_addralign);
LIBELF_COPY_U32(sh32, s, sh_entsize);
return (1);
}
+153
Переглянути файл
@@ -0,0 +1,153 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <gelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: gelf_sym.c 189 2008-07-20 10:38:08Z jkoshy $");
GElf_Sym *
gelf_getsym(Elf_Data *d, int ndx, GElf_Sym *dst)
{
int ec;
Elf *e;
Elf_Scn *scn;
Elf32_Sym *sym32;
Elf64_Sym *sym64;
size_t msz;
uint32_t sh_type;
if (d == NULL || ndx < 0 || dst == NULL ||
(scn = d->d_scn) == NULL ||
(e = scn->s_elf) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
ec = e->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32)
sh_type = scn->s_shdr.s_shdr32.sh_type;
else
sh_type = scn->s_shdr.s_shdr64.sh_type;
if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
msz = _libelf_msize(ELF_T_SYM, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if (ec == ELFCLASS32) {
sym32 = (Elf32_Sym *) d->d_buf + ndx;
dst->st_name = sym32->st_name;
dst->st_value = (Elf64_Addr) sym32->st_value;
dst->st_size = (Elf64_Xword) sym32->st_size;
dst->st_info = ELF64_ST_INFO(ELF32_ST_BIND(sym32->st_info),
ELF32_ST_TYPE(sym32->st_info));
dst->st_other = sym32->st_other;
dst->st_shndx = sym32->st_shndx;
} else {
sym64 = (Elf64_Sym *) d->d_buf + ndx;
*dst = *sym64;
}
return (dst);
}
int
gelf_update_sym(Elf_Data *d, int ndx, GElf_Sym *gs)
{
int ec;
Elf *e;
Elf_Scn *scn;
Elf32_Sym *sym32;
Elf64_Sym *sym64;
size_t msz;
uint32_t sh_type;
if (d == NULL || ndx < 0 || gs == NULL ||
(scn = d->d_scn) == NULL ||
(e = scn->s_elf) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
ec = e->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32)
sh_type = scn->s_shdr.s_shdr32.sh_type;
else
sh_type = scn->s_shdr.s_shdr64.sh_type;
if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
msz = _libelf_msize(ELF_T_SYM, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if (ec == ELFCLASS32) {
sym32 = (Elf32_Sym *) d->d_buf + ndx;
sym32->st_name = gs->st_name;
sym32->st_info = gs->st_info;
sym32->st_other = gs->st_other;
sym32->st_shndx = gs->st_shndx;
LIBELF_COPY_U32(sym32, gs, st_value);
LIBELF_COPY_U32(sym32, gs, st_size);
} else {
sym64 = (Elf64_Sym *) d->d_buf + ndx;
*sym64 = *gs;
}
return (1);
}
+147
Переглянути файл
@@ -0,0 +1,147 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <gelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: gelf_syminfo.c 1166 2010-09-04 00:54:36Z jkoshy $");
#if LIBELF_CONFIG_SYMINFO
GElf_Syminfo *
gelf_getsyminfo(Elf_Data *d, int ndx, GElf_Syminfo *dst)
{
int ec;
Elf *e;
Elf_Scn *scn;
Elf32_Syminfo *syminfo32;
Elf64_Syminfo *syminfo64;
size_t msz;
uint32_t sh_type;
if (d == NULL || ndx < 0 || dst == NULL ||
(scn = d->d_scn) == NULL ||
(e = scn->s_elf) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
ec = e->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32)
sh_type = scn->s_shdr.s_shdr32.sh_type;
else
sh_type = scn->s_shdr.s_shdr64.sh_type;
if (_libelf_xlate_shtype(sh_type) != ELF_T_SYMINFO) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if (ec == ELFCLASS32) {
syminfo32 = (Elf32_Syminfo *) d->d_buf + ndx;
dst->si_boundto = syminfo32->si_boundto;
dst->si_flags = syminfo32->si_flags;
} else {
syminfo64 = (Elf64_Syminfo *) d->d_buf + ndx;
*dst = *syminfo64;
}
return (dst);
}
int
gelf_update_syminfo(Elf_Data *d, int ndx, GElf_Syminfo *gs)
{
int ec;
Elf *e;
Elf_Scn *scn;
Elf32_Syminfo *syminfo32;
Elf64_Syminfo *syminfo64;
size_t msz;
uint32_t sh_type;
if (d == NULL || ndx < 0 || gs == NULL ||
(scn = d->d_scn) == NULL ||
(e = scn->s_elf) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
ec = e->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32)
sh_type = scn->s_shdr.s_shdr32.sh_type;
else
sh_type = scn->s_shdr.s_shdr64.sh_type;
if (_libelf_xlate_shtype(sh_type) != ELF_T_SYMINFO) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
if (ec == ELFCLASS32) {
syminfo32 = (Elf32_Syminfo *) d->d_buf + ndx;
syminfo32->si_boundto = gs->si_boundto;
syminfo32->si_flags = gs->si_flags;
} else {
syminfo64 = (Elf64_Syminfo *) d->d_buf + ndx;
*syminfo64 = *gs;
}
return (1);
}
#endif /* LIBELF_CONFIG_SYMINFO */
+128
Переглянути файл
@@ -0,0 +1,128 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <gelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: gelf_symshndx.c 189 2008-07-20 10:38:08Z jkoshy $");
GElf_Sym *
gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst,
Elf32_Word *shindex)
{
int ec;
Elf *e;
Elf_Scn *scn;
size_t msz;
uint32_t sh_type;
if (gelf_getsym(d, ndx, dst) == 0)
return (NULL);
if (id == NULL || (scn = id->d_scn) == NULL ||
(e = scn->s_elf) == NULL || (e != d->d_scn->s_elf) ||
shindex == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
ec = e->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32)
sh_type = scn->s_shdr.s_shdr32.sh_type;
else
sh_type = scn->s_shdr.s_shdr64.sh_type;
if (_libelf_xlate_shtype(sh_type) != ELF_T_WORD ||
id->d_type != ELF_T_WORD) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
msz = _libelf_msize(ELF_T_WORD, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= id->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
*shindex = ((Elf32_Word *) id->d_buf)[ndx];
return (dst);
}
int
gelf_update_symshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *gs,
Elf32_Word xindex)
{
int ec;
Elf *e;
Elf_Scn *scn;
size_t msz;
uint32_t sh_type;
if (gelf_update_sym(d, ndx, gs) == 0)
return (0);
if (id == NULL || (scn = id->d_scn) == NULL ||
(e = scn->s_elf) == NULL || (e != d->d_scn->s_elf)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
ec = e->e_class;
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (ec == ELFCLASS32)
sh_type = scn->s_shdr.s_shdr32.sh_type;
else
sh_type = scn->s_shdr.s_shdr64.sh_type;
if (_libelf_xlate_shtype(sh_type) != ELF_T_WORD ||
d->d_type != ELF_T_WORD) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
msz = _libelf_msize(ELF_T_WORD, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= id->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
*(((Elf32_Word *) id->d_buf) + ndx) = xindex;
return (1);
}
+81
Переглянути файл
@@ -0,0 +1,81 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <gelf.h>
#include <libelf.h>
#include <string.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: gelf_xlate.c 1678 2011-07-28 04:36:34Z jkoshy $");
Elf_Data *
elf32_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned int encoding)
{
return _libelf_xlate(dst, src, encoding, ELFCLASS32, ELF_TOFILE);
}
Elf_Data *
elf64_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned int encoding)
{
return _libelf_xlate(dst, src, encoding, ELFCLASS64, ELF_TOFILE);
}
Elf_Data *
elf32_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned int encoding)
{
return _libelf_xlate(dst, src, encoding, ELFCLASS32, ELF_TOMEMORY);
}
Elf_Data *
elf64_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned int encoding)
{
return _libelf_xlate(dst, src, encoding, ELFCLASS64, ELF_TOMEMORY);
}
Elf_Data *
gelf_xlatetom(Elf *e, Elf_Data *dst, const Elf_Data *src,
unsigned int encoding)
{
if (e != NULL)
return (_libelf_xlate(dst, src, encoding, e->e_class,
ELF_TOMEMORY));
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
Elf_Data *
gelf_xlatetof(Elf *e, Elf_Data *dst, const Elf_Data *src,
unsigned int encoding)
{
if (e != NULL)
return (_libelf_xlate(dst, src, encoding, e->e_class,
ELF_TOFILE));
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
+262
Переглянути файл
@@ -0,0 +1,262 @@
/*-
* Copyright (c) 2006,2008-2010 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: libelf.h 1345 2011-01-01 11:17:52Z jkoshy $
*/
#ifndef _LIBELF_H_
#define _LIBELF_H_
#include <sys/types.h>
#include <sys/queue.h>
#include <elfdefinitions.h>
#ifndef EM_HSAIL
#define EM_HSAIL 0xAF5A
#endif
/* Library private data structures */
typedef struct _Elf Elf;
typedef struct _Elf_Scn Elf_Scn;
typedef struct _Elf_Mem Elf_Mem;
/* File types */
typedef enum {
ELF_K_NONE = 0,
ELF_K_AR, /* `ar' archives */
ELF_K_COFF, /* COFF files (unsupported) */
ELF_K_ELF, /* ELF files */
ELF_K_NUM
} Elf_Kind;
#define ELF_K_FIRST ELF_K_NONE
#define ELF_K_LAST ELF_K_NUM
/* Data types */
typedef enum {
ELF_T_ADDR,
ELF_T_BYTE,
ELF_T_CAP,
ELF_T_DYN,
ELF_T_EHDR,
ELF_T_HALF,
ELF_T_LWORD,
ELF_T_MOVE,
ELF_T_MOVEP,
ELF_T_NOTE,
ELF_T_OFF,
ELF_T_PHDR,
ELF_T_REL,
ELF_T_RELA,
ELF_T_SHDR,
ELF_T_SWORD,
ELF_T_SXWORD,
ELF_T_SYMINFO,
ELF_T_SYM,
ELF_T_VDEF,
ELF_T_VNEED,
ELF_T_WORD,
ELF_T_XWORD,
ELF_T_GNUHASH, /* GNU style hash tables. */
ELF_T_NUM
} Elf_Type;
#define ELF_T_FIRST ELF_T_ADDR
#define ELF_T_LAST ELF_T_GNUHASH
/* Commands */
typedef enum {
ELF_C_NULL = 0,
ELF_C_CLR,
ELF_C_FDDONE,
ELF_C_FDREAD,
ELF_C_RDWR,
ELF_C_READ,
ELF_C_SET,
ELF_C_WRITE,
ELF_C_NUM
} Elf_Cmd;
#define ELF_C_FIRST ELF_C_NULL
#define ELF_C_LAST ELF_C_NUM
/*
* An `Elf_Data' structure describes data in an
* ELF section.
*/
typedef struct _Elf_Data {
/*
* `Public' members that are part of the ELF(3) API.
*/
uint64_t d_align;
void *d_buf;
uint64_t d_off;
uint64_t d_size;
Elf_Type d_type;
unsigned int d_version;
/*
* Members that are not part of the public API.
*/
Elf_Scn *d_scn; /* containing section */
unsigned int d_flags;
STAILQ_ENTRY(_Elf_Data) d_next;
} Elf_Data;
/*
* An `Elf_Arhdr' structure describes an archive
* header.
*/
typedef struct {
time_t ar_date;
char *ar_name; /* archive member name */
gid_t ar_gid;
mode_t ar_mode;
char *ar_rawname; /* 'raw' member name */
size_t ar_size;
uid_t ar_uid;
/*
* Members that are not part of the public API.
*/
int ar_flags;
} Elf_Arhdr;
/*
* An `Elf_Arsym' describes an entry in the archive
* symbol table.
*/
typedef struct {
off_t as_off; /* byte offset to member's header */
unsigned long as_hash; /* elf_hash() value for name */
char *as_name; /* null terminated symbol name */
} Elf_Arsym;
/*
* Error numbers.
*/
enum Elf_Error {
ELF_E_NONE, /* No error */
ELF_E_ARCHIVE, /* Malformed ar(1) archive */
ELF_E_ARGUMENT, /* Invalid argument */
ELF_E_CLASS, /* Mismatched ELF class */
ELF_E_DATA, /* Invalid data descriptor */
ELF_E_HEADER, /* Missing or malformed ELF header */
ELF_E_IO, /* I/O error */
ELF_E_LAYOUT, /* Layout constraint violation */
ELF_E_MODE, /* Wrong mode for ELF descriptor */
ELF_E_RANGE, /* Value out of range */
ELF_E_RESOURCE, /* Resource exhaustion */
ELF_E_SECTION, /* Invalid section descriptor */
ELF_E_SEQUENCE, /* API calls out of sequence */
ELF_E_UNIMPL, /* Feature is unimplemented */
ELF_E_VERSION, /* Unknown API version */
ELF_E_NUM /* Max error number */
};
/*
* Flags defined by the API.
*/
#define ELF_F_LAYOUT 0x001U /* application will layout the file */
#define ELF_F_DIRTY 0x002U /* a section or ELF file is dirty */
/* ELF(3) API extensions. */
#define ELF_F_ARCHIVE 0x100U /* archive creation */
#define ELF_F_ARCHIVE_SYSV 0x200U /* SYSV style archive */
__BEGIN_DECLS
Elf *elf_begin(int _fd, Elf_Cmd _cmd, Elf *_elf, Elf_Mem *_mem);
int elf_cntl(Elf *_elf, Elf_Cmd _cmd);
int elf_end(Elf *_elf);
const char *elf_errmsg(int _error);
int elf_errno(void);
void elf_fill(int _fill);
unsigned int elf_flagarhdr(Elf_Arhdr *_arh, Elf_Cmd _cmd,
unsigned int _flags);
unsigned int elf_flagdata(Elf_Data *_data, Elf_Cmd _cmd,
unsigned int _flags);
unsigned int elf_flagehdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags);
unsigned int elf_flagelf(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags);
unsigned int elf_flagphdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags);
unsigned int elf_flagscn(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags);
unsigned int elf_flagshdr(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags);
Elf_Arhdr *elf_getarhdr(Elf *_elf);
Elf_Arsym *elf_getarsym(Elf *_elf, size_t *_ptr);
off_t elf_getbase(Elf *_elf);
Elf_Data *elf_getdata(Elf_Scn *, Elf_Data *);
void elf_removedata(Elf_Scn *s, Elf_Data *d);
char *elf_getident(Elf *_elf, size_t *_ptr);
int elf_getphdrnum(Elf *_elf, size_t *_dst);
int elf_getphnum(Elf *_elf, size_t *_dst); /* Deprecated */
Elf_Scn *elf_getscn(Elf *_elf, size_t _index);
int elf_getshdrnum(Elf *_elf, size_t *_dst);
int elf_getshnum(Elf *_elf, size_t *_dst); /* Deprecated */
int elf_getshdrstrndx(Elf *_elf, size_t *_dst);
int elf_getshstrndx(Elf *_elf, size_t *_dst); /* Deprecated */
unsigned long elf_hash(const char *_name);
Elf_Kind elf_kind(Elf *_elf);
Elf *elf_memory(char *_image, size_t _size, Elf_Mem *mem);
size_t elf_ndxscn(Elf_Scn *_scn);
Elf_Data *elf_newdata(Elf_Scn *_scn);
Elf_Scn *elf_newscn(Elf *_elf);
Elf_Scn *elf_nextscn(Elf *_elf, Elf_Scn *_scn);
Elf_Cmd elf_next(Elf *_elf);
off_t elf_rand(Elf *_elf, off_t _off);
Elf_Data *elf_rawdata(Elf_Scn *_scn, Elf_Data *_data);
char *elf_rawfile(Elf *_elf, size_t *_size);
int elf_setshstrndx(Elf *_elf, size_t _shnum);
char *elf_strptr(Elf *_elf, size_t _section, size_t _offset);
off_t elf_update(Elf *_elf, Elf_Cmd _cmd);
unsigned int elf_version(unsigned int _version);
long elf32_checksum(Elf *_elf);
size_t elf32_fsize(Elf_Type _type, size_t _count,
unsigned int _version);
Elf32_Ehdr *elf32_getehdr(Elf *_elf);
Elf32_Phdr *elf32_getphdr(Elf *_elf);
Elf32_Shdr *elf32_getshdr(Elf_Scn *_scn);
Elf32_Ehdr *elf32_newehdr(Elf *_elf);
Elf32_Phdr *elf32_newphdr(Elf *_elf, size_t _count);
Elf_Data *elf32_xlatetof(Elf_Data *_dst, const Elf_Data *_src,
unsigned int _enc);
Elf_Data *elf32_xlatetom(Elf_Data *_dst, const Elf_Data *_src,
unsigned int _enc);
long elf64_checksum(Elf *_elf);
size_t elf64_fsize(Elf_Type _type, size_t _count,
unsigned int _version);
Elf64_Ehdr *elf64_getehdr(Elf *_elf);
Elf64_Phdr *elf64_getphdr(Elf *_elf);
Elf64_Shdr *elf64_getshdr(Elf_Scn *_scn);
Elf64_Ehdr *elf64_newehdr(Elf *_elf);
Elf64_Phdr *elf64_newphdr(Elf *_elf, size_t _count);
Elf_Data *elf64_xlatetof(Elf_Data *_dst, const Elf_Data *_src,
unsigned int _enc);
Elf_Data *elf64_xlatetom(Elf_Data *_dst, const Elf_Data *_src,
unsigned int _enc);
__END_DECLS
#endif /* _LIBELF_H_ */
+185
Переглянути файл
@@ -0,0 +1,185 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <sys/types.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: libelf_align.c 1169 2010-09-04 01:06:31Z jkoshy $");
struct align {
int a32;
int a64;
};
#ifdef __GNUC__
#define MALIGN(N) { \
.a32 = __alignof__(Elf32_##N), \
.a64 = __alignof__(Elf64_##N) \
}
#define MALIGN64(V) { \
.a32 = 0, \
.a64 = __alignof__(Elf64_##V) \
}
#define MALIGN_WORD() { \
.a32 = __alignof__(int32_t), \
.a64 = __alignof__(int64_t) \
}
#elif !defined(_MSC_VER)
#error Need the __alignof__ builtin.
#endif
#define UNSUPPORTED() { \
.a32 = 0, \
.a64 = 0 \
}
static struct align malign[ELF_T_NUM] = {
#if defined(__GNUC__)
[ELF_T_ADDR] = MALIGN(Addr),
[ELF_T_BYTE] = { .a32 = 1, .a64 = 1 },
#if LIBELF_CONFIG_CAP
[ELF_T_CAP] = MALIGN(Cap),
#endif
[ELF_T_DYN] = MALIGN(Dyn),
[ELF_T_EHDR] = MALIGN(Ehdr),
[ELF_T_HALF] = MALIGN(Half),
#if LIBELF_CONFIG_LWORD
[ELF_T_LWORD] = MALIGN(Lword),
#endif
#if LIBELF_CONFIG_MOVE
[ELF_T_MOVE] = MALIGN(Move),
#endif
[ELF_T_MOVEP] = UNSUPPORTED(),
#if LIBELF_CONFIG_NOTE
[ELF_T_NOTE] = MALIGN(Nhdr),
#endif
[ELF_T_OFF] = MALIGN(Off),
[ELF_T_PHDR] = MALIGN(Phdr),
[ELF_T_REL] = MALIGN(Rel),
[ELF_T_RELA] = MALIGN(Rela),
[ELF_T_SHDR] = MALIGN(Shdr),
[ELF_T_SWORD] = MALIGN(Sword),
[ELF_T_SXWORD] = MALIGN64(Sxword),
[ELF_T_SYM] = MALIGN(Sym),
#if LIBELF_CONFIG_SYMINFO
[ELF_T_SYMINFO] = MALIGN(Syminfo),
#endif
#if LIBELF_CONFIG_VDEF
[ELF_T_VDEF] = MALIGN(Verdef),
#endif
#if LIBELF_CONFIG_VNEED
[ELF_T_VNEED] = MALIGN(Verneed),
#endif
[ELF_T_WORD] = MALIGN(Word),
[ELF_T_XWORD] = MALIGN64(Xword),
[ELF_T_GNUHASH] = MALIGN_WORD()
#elif defined(_MSC_VER)
{ 4, 8 }, { 1, 1 }, { 4, 8 }, { 4, 8 }, { 4, 8 },
{ 2, 2 }, { 8, 8 }, { 8, 8 }, { 0, 0 }, { 4, 4 },
{ 4, 8 }, { 4, 8 }, { 4, 8 }, { 4, 8 }, { 4, 8 },
{ 4, 4 }, { 0, 8 }, { 4, 8 }, { 2, 2 }, { 4, 4 },
{ 4, 4 }, { 4, 4 }, { 0, 8 }, { 4, 8 }
#else
#error
#endif
};
int
_libelf_malign(Elf_Type t, int elfclass)
{
if (t >= ELF_T_NUM || (int) t < 0)
return (0);
return (elfclass == ELFCLASS32 ? malign[t].a32 :
malign[t].a64);
}
#define FALIGN(A32,A64) { .a32 = (A32), .a64 = (A64) }
static struct align falign[ELF_T_NUM] = {
#if defined(__GNUC__)
[ELF_T_ADDR] = FALIGN(4,8),
[ELF_T_BYTE] = FALIGN(1,1),
#if LIBELF_CONFIG_CAP
[ELF_T_CAP] = FALIGN(4,8),
#endif
[ELF_T_DYN] = FALIGN(4,8),
[ELF_T_EHDR] = FALIGN(4,8),
[ELF_T_HALF] = FALIGN(2,2),
#if LIBELF_CONFIG_LWORD
[ELF_T_LWORD] = FALIGN(8,8),
#endif
#if LIBELF_CONFIG_MOVE
[ELF_T_MOVE] = FALIGN(8,8),
#endif
[ELF_T_MOVEP] = UNSUPPORTED(),
#if LIBELF_CONFIG_NOTE
[ELF_T_NOTE] = FALIGN(4,4),
#endif
[ELF_T_OFF] = FALIGN(4,8),
[ELF_T_PHDR] = FALIGN(4,8),
[ELF_T_REL] = FALIGN(4,8),
[ELF_T_RELA] = FALIGN(4,8),
[ELF_T_SHDR] = FALIGN(4,8),
[ELF_T_SWORD] = FALIGN(4,4),
[ELF_T_SXWORD] = FALIGN(0,8),
[ELF_T_SYM] = FALIGN(4,8),
#if LIBELF_CONFIG_SYMINFO
[ELF_T_SYMINFO] = FALIGN(2,2),
#endif
#if LIBELF_CONFIG_VDEF
[ELF_T_VDEF] = FALIGN(4,4),
#endif
#if LIBELF_CONFIG_VNEED
[ELF_T_VNEED] = FALIGN(4,4),
#endif
[ELF_T_WORD] = FALIGN(4,4),
[ELF_T_XWORD] = FALIGN(0,8),
[ELF_T_GNUHASH] = FALIGN(4,8)
#elif defined(_MSC_VER)
{ 4, 8 }, { 1, 1 }, { 4, 8 }, { 4, 8 }, { 4, 8 },
{ 2, 2 }, { 8, 8 }, { 8, 8 }, { 0, 0 }, { 4, 4 },
{ 4, 8 }, { 4, 8 }, { 4, 8 }, { 4, 8 }, { 4, 8 },
{ 4, 4 }, { 0, 8 }, { 4, 8 }, { 2, 2 }, { 4, 4 },
{ 4, 4 }, { 4, 4 }, { 0, 8 }, { 4, 8 }
#else
#error
#endif
};
int
_libelf_falign(Elf_Type t, int elfclass)
{
if (t >= ELF_T_NUM || (int) t < 0)
return (0);
return (elfclass == ELFCLASS32 ? falign[t].a32 :
falign[t].a64);
}
+228
Переглянути файл
@@ -0,0 +1,228 @@
/*-
* Copyright (c) 2006,2008,2010 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Internal APIs
*/
#include <sys/cdefs.h>
#if !defined(WIN32)
#include <sys/errno.h>
#endif
#include <assert.h>
#include <errno.h>
#include <libelf.h>
#include <stdlib.h>
#include <string.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: libelf_allocate.c 1341 2011-01-01 04:28:29Z jkoshy $");
Elf *
_libelf_allocate_elf(Elf_Mem *mem)
{
Elf *e;
if (mem != NULL) {
if ((e = mem->alloc(sizeof(*e))) == NULL) {
LIBELF_SET_ERROR(RESOURCE, errno);
return NULL;
}
e->e_mem.dealloc = mem->dealloc;
e->e_mem.alloc = mem->alloc;
} else {
if ((e = malloc(sizeof(*e))) == NULL) {
LIBELF_SET_ERROR(RESOURCE, errno);
return NULL;
}
e->e_mem.dealloc = &free;
e->e_mem.alloc = &malloc;
}
e->e_activations = 1;
e->e_hdr.e_rawhdr = NULL;
e->e_byteorder = ELFDATANONE;
e->e_class = ELFCLASSNONE;
e->e_cmd = ELF_C_NULL;
e->e_fd = -1;
e->e_flags = 0;
e->e_kind = ELF_K_NONE;
e->e_parent = NULL;
e->e_rawfile = NULL;
e->e_rawsize = 0;
e->e_version = LIBELF_PRIVATE(version);
(void) memset(&e->e_u, 0, sizeof(e->e_u));
return (e);
}
void
_libelf_init_elf(Elf *e, Elf_Kind kind)
{
assert(e != NULL);
assert(e->e_kind == ELF_K_NONE);
e->e_kind = kind;
switch (kind) {
case ELF_K_ELF:
STAILQ_INIT(&e->e_u.e_elf.e_scn);
break;
default:
break;
}
}
#define FREE(E, P) do { \
if (P) \
E->e_mem.dealloc(P); \
} while (0)
Elf *
_libelf_release_elf(Elf *e)
{
Elf_Arhdr *arh;
switch (e->e_kind) {
case ELF_K_AR:
FREE(e, e->e_u.e_ar.e_symtab);
break;
case ELF_K_ELF:
switch (e->e_class) {
case ELFCLASS32:
FREE(e, e->e_u.e_elf.e_ehdr.e_ehdr32);
FREE(e, e->e_u.e_elf.e_phdr.e_phdr32);
break;
case ELFCLASS64:
FREE(e, e->e_u.e_elf.e_ehdr.e_ehdr64);
FREE(e, e->e_u.e_elf.e_phdr.e_phdr64);
break;
}
assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn));
if (e->e_flags & LIBELF_F_AR_HEADER) {
arh = e->e_hdr.e_arhdr;
FREE(e, arh->ar_name);
FREE(e, arh->ar_rawname);
e->e_mem.dealloc(arh);
}
break;
default:
break;
}
e->e_mem.dealloc(e);
return (NULL);
}
Elf_Data *
_libelf_allocate_data(Elf_Scn *s)
{
Elf_Data *d;
if ((d = s->s_elf->e_mem.alloc(sizeof(Elf_Data))) == NULL) {
LIBELF_SET_ERROR(RESOURCE, 0);
return (NULL);
}
memset(d, 0, sizeof(*d));
d->d_scn = s;
return (d);
}
Elf_Data *
_libelf_release_data(Elf_Data *d)
{
if (d->d_flags & LIBELF_F_DATA_MALLOCED)
d->d_scn->s_elf->e_mem.dealloc(d->d_buf);
d->d_scn->s_elf->e_mem.dealloc(d);
return (NULL);
}
Elf_Scn *
_libelf_allocate_scn(Elf *e, size_t ndx)
{
Elf_Scn *s;
if ((s = e->e_mem.alloc(sizeof(Elf_Scn))) == NULL) {
LIBELF_SET_ERROR(RESOURCE, errno);
return (NULL);
}
memset(s, 0, sizeof(*s));
s->s_elf = e;
s->s_ndx = ndx;
STAILQ_INIT(&s->s_data);
STAILQ_INIT(&s->s_rawdata);
STAILQ_INSERT_TAIL(&e->e_u.e_elf.e_scn, s, s_next);
return (s);
}
Elf_Scn *
_libelf_release_scn(Elf_Scn *s)
{
Elf *e;
Elf_Data *d, *td;
assert(s != NULL);
STAILQ_FOREACH_SAFE(d, &s->s_data, d_next, td) {
STAILQ_REMOVE(&s->s_data, d, _Elf_Data, d_next);
d = _libelf_release_data(d);
}
STAILQ_FOREACH_SAFE(d, &s->s_rawdata, d_next, td) {
assert((d->d_flags & LIBELF_F_DATA_MALLOCED) == 0);
STAILQ_REMOVE(&s->s_rawdata, d, _Elf_Data, d_next);
d = _libelf_release_data(d);
}
e = s->s_elf;
assert(e != NULL);
STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn, s_next);
e->e_mem.dealloc(s);
return (NULL);
}
+458
Переглянути файл
@@ -0,0 +1,458 @@
/*-
* Copyright (c) 2006,2008,2010 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <ctype.h>
#include <libelf.h>
#include <stdlib.h>
#include <string.h>
#include "_libelf.h"
#include "_libelf_ar.h"
LIBELF_VCSID("$Id: libelf_ar.c 1341 2011-01-01 04:28:29Z jkoshy $");
#define LIBELF_NALLOC_SIZE 16
/*
* `ar' archive handling.
*
* `ar' archives start with signature `ARMAG'. Each archive member is
* preceded by a header containing meta-data for the member. This
* header is described in <ar.h> (struct ar_hdr). The header always
* starts on an even address. File data is padded with "\n"
* characters to keep this invariant.
*
* Special considerations for `ar' archives:
*
* There are two variants of the `ar' archive format: traditional BSD
* and SVR4. These differ in the way long file names are treated, and
* in the layout of the archive symbol table.
*
* The `ar' header only has space for a 16 character file name.
*
* In the SVR4 format, file names are terminated with a '/', so this
* effectively leaves 15 characters for the actual file name. Longer
* file names stored in a separate 'string table' and referenced
* indirectly from the name field. The string table itself appears as
* an archive member with name "// ". An `indirect' file name in an
* `ar' header matches the pattern "/[0-9]*". The digits form a
* decimal number that corresponds to a byte offset into the string
* table where the actual file name of the object starts. Strings in
* the string table are padded to start on even addresses.
*
* In the BSD format, file names can be upto 16 characters. File
* names shorter than 16 characters are padded to 16 characters using
* (ASCII) space characters. File names with embedded spaces and file
* names longer than 16 characters are stored immediately after the
* archive header and the name field set to a special indirect name
* matching the pattern "#1/[0-9]+". The digits form a decimal number
* that corresponds to the actual length of the file name following
* the archive header. The content of the archive member immediately
* follows the file name, and the size field of the archive member
* holds the sum of the sizes of the member and of the appended file
* name.
*
* Archives may also have a symbol table (see ranlib(1)), mapping
* program symbols to object files inside the archive.
*
* In the SVR4 format, a symbol table uses a file name of "/ " in its
* archive header. The symbol table is structured as:
* - a 4-byte count of entries stored as a binary value, MSB first
* - 'n' 4-byte offsets, stored as binary values, MSB first
* - 'n' NUL-terminated strings, for ELF symbol names, stored unpadded.
*
* In the BSD format, the symbol table uses a file name of "__.SYMDEF".
* It is structured as two parts:
* - The first part is an array of "ranlib" structures preceded by
* the size of the array in bytes. Each "ranlib" structure
* describes one symbol. Each structure contains an offset into
* the string table for the symbol name, and a file offset into the
* archive for the member defining the symbol.
* - The second part is a string table containing NUL-terminated
* strings, preceded by the size of the string table in bytes.
*
* If the symbol table and string table are is present in an archive
* they must be the very first objects and in that order.
*/
/*
* Retrieve an archive header descriptor.
*/
Elf_Arhdr *
_libelf_ar_gethdr(Elf *e)
{
Elf *parent;
char *namelen;
Elf_Arhdr *eh;
size_t n, nlen;
struct ar_hdr *arh;
if ((parent = e->e_parent) == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
assert((e->e_flags & LIBELF_F_AR_HEADER) == 0);
arh = (struct ar_hdr *) (uintptr_t) e->e_hdr.e_rawhdr;
assert((uintptr_t) arh >= (uintptr_t) parent->e_rawfile + SARMAG);
assert((uintptr_t) arh <= (uintptr_t) parent->e_rawfile +
parent->e_rawsize - sizeof(struct ar_hdr));
if ((eh = e->e_mem.alloc(sizeof(Elf_Arhdr))) == NULL) {
LIBELF_SET_ERROR(RESOURCE, 0);
return (NULL);
}
e->e_hdr.e_arhdr = eh;
e->e_flags |= LIBELF_F_AR_HEADER;
eh->ar_name = eh->ar_rawname = NULL;
if ((eh->ar_name = _libelf_ar_get_translated_name(arh, parent)) ==
NULL)
goto error;
if (_libelf_ar_get_number(arh->ar_uid, sizeof(arh->ar_uid), 10,
&n) == 0)
goto error;
eh->ar_uid = (uid_t) n;
if (_libelf_ar_get_number(arh->ar_gid, sizeof(arh->ar_gid), 10,
&n) == 0)
goto error;
eh->ar_gid = (gid_t) n;
if (_libelf_ar_get_number(arh->ar_mode, sizeof(arh->ar_mode), 8,
&n) == 0)
goto error;
eh->ar_mode = (mode_t) n;
if (_libelf_ar_get_number(arh->ar_size, sizeof(arh->ar_size), 10,
&n) == 0)
goto error;
/*
* Get the true size of the member if extended naming is being used.
*/
if (IS_EXTENDED_BSD_NAME(arh->ar_name)) {
namelen = arh->ar_name +
LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE;
if (_libelf_ar_get_number(namelen, sizeof(arh->ar_name) -
LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10, &nlen) == 0)
goto error;
n -= nlen;
}
eh->ar_size = n;
if ((eh->ar_rawname = _libelf_ar_get_raw_name(arh)) == NULL)
goto error;
eh->ar_flags = 0;
return (eh);
error:
if (eh) {
if (eh->ar_name)
e->e_mem.dealloc(eh->ar_name);
if (eh->ar_rawname)
e->e_mem.dealloc(eh->ar_rawname);
e->e_mem.dealloc(eh);
}
e->e_flags &= ~LIBELF_F_AR_HEADER;
e->e_hdr.e_rawhdr = (char *) arh;
return (NULL);
}
Elf *
_libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf, Elf_Mem* mem)
{
Elf *e;
char *member, *namelen;
size_t nsz, sz;
off_t next;
struct ar_hdr *arh;
assert(elf->e_kind == ELF_K_AR);
next = elf->e_u.e_ar.e_next;
/*
* `next' is only set to zero by elf_next() when the last
* member of an archive is processed.
*/
if (next == (off_t) 0)
return (NULL);
assert((next & 1) == 0);
arh = (struct ar_hdr *) (elf->e_rawfile + next);
/*
* Retrieve the size of the member.
*/
if (_libelf_ar_get_number(arh->ar_size, sizeof(arh->ar_size), 10,
&sz) == 0) {
LIBELF_SET_ERROR(ARCHIVE, 0);
return (NULL);
}
/*
* Adjust the size field for members in BSD archives using
* extended naming.
*/
if (IS_EXTENDED_BSD_NAME(arh->ar_name)) {
namelen = arh->ar_name +
LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE;
if (_libelf_ar_get_number(namelen, sizeof(arh->ar_name) -
LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10, &nsz) == 0) {
LIBELF_SET_ERROR(ARCHIVE, 0);
return (NULL);
}
member = (char *) (arh + 1) + nsz;
sz -= nsz;
} else
member = (char *) (arh + 1);
if ((e = elf_memory((char *) member, sz, mem)) == NULL)
return (NULL);
e->e_fd = fd;
e->e_cmd = c;
e->e_hdr.e_rawhdr = (char *) arh;
elf->e_u.e_ar.e_nchildren++;
e->e_parent = elf;
return (e);
}
/*
* A BSD-style ar(1) symbol table has the following layout:
*
* - A count of bytes used by the following array of 'ranlib'
* structures, stored as a 'long'.
* - An array of 'ranlib' structures. Each array element is
* two 'long's in size.
* - A count of bytes used for the following symbol table.
* - The symbol table itself.
*/
/*
* A helper macro to read in a 'long' value from the archive. We use
* memcpy() since the source pointer may be misaligned with respect to
* the natural alignment for a C 'long'.
*/
#define GET_LONG(P, V)do { \
memcpy(&(V), (P), sizeof(long)); \
(P) += sizeof(long); \
} while (0)
Elf_Arsym *
_libelf_ar_process_bsd_symtab(Elf *e, size_t *count)
{
Elf_Arsym *symtab, *sym;
unsigned char *end, *p, *p0, *s, *s0;
const unsigned int entrysize = 2 * sizeof(long);
long arraysize, fileoffset, n, nentries, stroffset, strtabsize;
assert(e != NULL);
assert(count != NULL);
assert(e->e_u.e_ar.e_symtab == NULL);
symtab = NULL;
/*
* The BSD symbol table always contains the count fields even
* if there are no entries in it.
*/
if (e->e_u.e_ar.e_rawsymtabsz < 2 * sizeof(long))
goto symtaberror;
p = p0 = (unsigned char *) e->e_u.e_ar.e_rawsymtab;
end = p0 + e->e_u.e_ar.e_rawsymtabsz;
/*
* Retrieve the size of the array of ranlib descriptors and
* check it for validity.
*/
GET_LONG(p, arraysize);
if (p0 + arraysize >= end || (arraysize % entrysize != 0))
goto symtaberror;
/*
* Check the value of the string table size.
*/
s = p + arraysize;
GET_LONG(s, strtabsize);
s0 = s; /* Start of string table. */
if (s0 + strtabsize > end)
goto symtaberror;
nentries = arraysize / entrysize;
/*
* Allocate space for the returned Elf_Arsym array.
*/
if ((symtab = e->e_mem.alloc(sizeof(Elf_Arsym) * (nentries + 1))) == NULL) {
LIBELF_SET_ERROR(RESOURCE, 0);
return (NULL);
}
/* Read in symbol table entries. */
for (n = 0, sym = symtab; n < nentries; n++, sym++) {
GET_LONG(p, stroffset);
GET_LONG(p, fileoffset);
s = s0 + stroffset;
if (s >= end)
goto symtaberror;
sym->as_off = fileoffset;
sym->as_hash = elf_hash((char *) s);
sym->as_name = (char *) s;
}
/* Fill up the sentinel entry. */
sym->as_name = NULL;
sym->as_hash = ~0UL;
sym->as_off = (off_t) 0;
/* Remember the processed symbol table. */
e->e_u.e_ar.e_symtab = symtab;
*count = e->e_u.e_ar.e_symtabsz = nentries + 1;
return (symtab);
symtaberror:
if (symtab)
e->e_mem.dealloc(symtab);
LIBELF_SET_ERROR(ARCHIVE, 0);
return (NULL);
}
/*
* An SVR4-style ar(1) symbol table has the following layout:
*
* - The first 4 bytes are a binary count of the number of entries in the
* symbol table, stored MSB-first.
* - Then there are 'n' 4-byte binary offsets, also stored MSB first.
* - Following this, there are 'n' null-terminated strings.
*/
#define GET_WORD(P, V) do { \
(V) = 0; \
(V) = (P)[0]; (V) <<= 8; \
(V) += (P)[1]; (V) <<= 8; \
(V) += (P)[2]; (V) <<= 8; \
(V) += (P)[3]; \
} while (0)
#define INTSZ 4
Elf_Arsym *
_libelf_ar_process_svr4_symtab(Elf *e, size_t *count)
{
size_t n, nentries, off;
Elf_Arsym *symtab, *sym;
char *p, *s, *end;
assert(e != NULL);
assert(count != NULL);
assert(e->e_u.e_ar.e_symtab == NULL);
symtab = NULL;
if (e->e_u.e_ar.e_rawsymtabsz < INTSZ)
goto symtaberror;
p = e->e_u.e_ar.e_rawsymtab;
end = p + e->e_u.e_ar.e_rawsymtabsz;
GET_WORD(p, nentries);
p += INTSZ;
if (nentries == 0 || p + nentries * INTSZ >= end)
goto symtaberror;
/* Allocate space for a nentries + a sentinel. */
if ((symtab = e->e_mem.alloc(sizeof(Elf_Arsym) * (nentries+1))) == NULL) {
LIBELF_SET_ERROR(RESOURCE, 0);
return (NULL);
}
s = p + (nentries * INTSZ); /* start of the string table. */
for (n = nentries, sym = symtab; n > 0; n--) {
if (s >= end)
goto symtaberror;
off = 0;
GET_WORD(p, off);
sym->as_off = off;
sym->as_hash = elf_hash((char *) s);
sym->as_name = (char *) s;
p += INTSZ;
sym++;
for (; s < end && *s++ != '\0';) /* skip to next string */
;
}
/* Fill up the sentinel entry. */
sym->as_name = NULL;
sym->as_hash = ~0UL;
sym->as_off = (off_t) 0;
*count = e->e_u.e_ar.e_symtabsz = nentries + 1;
e->e_u.e_ar.e_symtab = symtab;
return (symtab);
symtaberror:
if (symtab)
e->e_mem.dealloc(symtab);
LIBELF_SET_ERROR(ARCHIVE, 0);
return (NULL);
}
+354
Переглянути файл
@@ -0,0 +1,354 @@
/*-
* Copyright (c) 2006,2009,2010 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <libelf.h>
#include <stdlib.h>
#include <string.h>
#include "_libelf.h"
#include "_libelf_ar.h"
LIBELF_VCSID("$Id: libelf_ar_util.c 2066 2011-10-26 15:40:28Z jkoshy $");
/*
* Convert a string bounded by `start' and `start+sz' (exclusive) to a
* number in the specified base.
*/
int
_libelf_ar_get_number(const char *s, size_t sz, int base, size_t *ret)
{
int c, v;
size_t r;
const char *e;
assert(base <= 10);
e = s + sz;
/* skip leading blanks */
for (;s < e && (c = *s) == ' '; s++)
;
r = 0L;
for (;s < e; s++) {
if ((c = *s) == ' ')
break;
if (c < '0' || c > '9')
return (0);
v = c - '0';
if (v >= base) /* Illegal digit. */
break;
r *= base;
r += v;
}
*ret = r;
return (1);
}
/*
* Return the translated name for an archive member.
*/
char *
_libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar)
{
char c, *s;
size_t len, offset;
const char *buf, *p, *q, *r;
const size_t bufsize = sizeof(arh->ar_name);
assert(arh != NULL);
assert(ar->e_kind == ELF_K_AR);
assert((const char *) arh >= ar->e_rawfile &&
(const char *) arh < ar->e_rawfile + ar->e_rawsize);
buf = arh->ar_name;
/*
* Check for extended naming.
*
* If the name matches the pattern "^/[0-9]+", it is an
* SVR4-style extended name. If the name matches the pattern
* "#1/[0-9]+", the entry uses BSD style extended naming.
*/
if (buf[0] == '/' && (c = buf[1]) >= '0' && c <= '9') {
/*
* The value in field ar_name is a decimal offset into
* the archive string table where the actual name
* resides.
*/
if (_libelf_ar_get_number(buf + 1, bufsize - 1, 10,
&offset) == 0) {
LIBELF_SET_ERROR(ARCHIVE, 0);
return (NULL);
}
if (offset > ar->e_u.e_ar.e_rawstrtabsz) {
LIBELF_SET_ERROR(ARCHIVE, 0);
return (NULL);
}
p = q = ar->e_u.e_ar.e_rawstrtab + offset;
r = ar->e_u.e_ar.e_rawstrtab + ar->e_u.e_ar.e_rawstrtabsz;
for (; p < r && *p != '/'; p++)
;
len = p - q + 1; /* space for the trailing NUL */
if ((s = ar->e_mem.alloc(len)) == NULL) {
LIBELF_SET_ERROR(RESOURCE, 0);
return (NULL);
}
(void) strncpy(s, q, len - 1);
s[len - 1] = '\0';
return (s);
} else if (IS_EXTENDED_BSD_NAME(buf)) {
r = buf + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE;
if (_libelf_ar_get_number(r, bufsize -
LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10,
&len) == 0) {
LIBELF_SET_ERROR(ARCHIVE, 0);
return (NULL);
}
/*
* Allocate space for the file name plus a
* trailing NUL.
*/
if ((s = ar->e_mem.alloc(len + 1)) == NULL) {
LIBELF_SET_ERROR(RESOURCE, 0);
return (NULL);
}
/*
* The file name follows the archive header.
*/
q = (const char *) (arh + 1);
(void) strncpy(s, q, len);
s[len] = '\0';
return (s);
}
/*
* A 'normal' name.
*
* Skip back over trailing blanks from the end of the field.
* In the SVR4 format, a '/' is used as a terminator for
* non-special names.
*/
for (q = buf + bufsize - 1; q >= buf && *q == ' '; --q)
;
if (q >= buf) {
if (*q == '/') {
/*
* SVR4 style names: ignore the trailing
* character '/', but only if the name is not
* one of the special names "/" and "//".
*/
if (q > buf + 1 ||
(q == (buf + 1) && *buf != '/'))
q--;
}
len = q - buf + 2; /* Add space for a trailing NUL. */
} else {
/* The buffer only had blanks. */
buf = "";
len = 1;
}
if ((s = ar->e_mem.alloc(len)) == NULL) {
LIBELF_SET_ERROR(RESOURCE, 0);
return (NULL);
}
(void) strncpy(s, buf, len - 1);
s[len - 1] = '\0';
return (s);
}
/*
* Return the raw name for an archive member, inclusive of any
* formatting characters.
*/
char *
_libelf_ar_get_raw_name(const struct ar_hdr *arh)
{
char *rawname;
const size_t namesz = sizeof(arh->ar_name);
if ((rawname = malloc(namesz + 1)) == NULL) {
LIBELF_SET_ERROR(RESOURCE, 0);
return (NULL);
}
(void) strncpy(rawname, arh->ar_name, namesz);
rawname[namesz] = '\0';
return (rawname);
}
/*
* Open an 'ar' archive.
*/
Elf *
_libelf_ar_open(Elf *e)
{
int scanahead;
char *s, *end;
size_t sz;
struct ar_hdr arh;
e->e_kind = ELF_K_AR;
e->e_u.e_ar.e_nchildren = 0;
e->e_u.e_ar.e_next = (off_t) -1;
/*
* Look for special members.
*/
s = e->e_rawfile + SARMAG;
end = e->e_rawfile + e->e_rawsize;
assert(e->e_rawsize > 0);
/*
* We use heuristics to determine the flavor of the archive we
* are examining.
*
* SVR4 flavor archives use the name "/ " and "// " for
* special members.
*
* In BSD flavor archives the symbol table, if present, is the
* first archive with name "__.SYMDEF".
*/
#define READ_AR_HEADER(S, ARH, SZ, END) \
do { \
if ((S) + sizeof((ARH)) > (END)) \
goto error; \
(void) memcpy(&(ARH), (S), sizeof((ARH))); \
if ((ARH).ar_fmag[0] != '`' || (ARH).ar_fmag[1] != '\n') \
goto error; \
if (_libelf_ar_get_number((ARH).ar_size, \
sizeof((ARH).ar_size), 10, &(SZ)) == 0) \
goto error; \
} while (0)
READ_AR_HEADER(s, arh, sz, end);
/*
* Handle special archive members for the SVR4 format.
*/
if (arh.ar_name[0] == '/') {
assert(sz > 0);
e->e_flags |= LIBELF_F_AR_VARIANT_SVR4;
scanahead = 0;
/*
* The symbol table (file name "/ ") always comes before the
* string table (file name "// ").
*/
if (arh.ar_name[1] == ' ') {
/* "/ " => symbol table. */
scanahead = 1; /* The string table to follow. */
s += sizeof(arh);
e->e_u.e_ar.e_rawsymtab = s;
e->e_u.e_ar.e_rawsymtabsz = sz;
sz = LIBELF_ADJUST_AR_SIZE(sz);
s += sz;
} else if (arh.ar_name[1] == '/' && arh.ar_name[2] == ' ') {
/* "// " => string table for long file names. */
s += sizeof(arh);
e->e_u.e_ar.e_rawstrtab = s;
e->e_u.e_ar.e_rawstrtabsz = sz;
sz = LIBELF_ADJUST_AR_SIZE(sz);
s += sz;
}
/*
* If the string table hasn't been seen yet, look for
* it in the next member.
*/
if (scanahead) {
READ_AR_HEADER(s, arh, sz, end);
/* "// " => string table for long file names. */
if (arh.ar_name[0] == '/' && arh.ar_name[1] == '/' &&
arh.ar_name[2] == ' ') {
s += sizeof(arh);
e->e_u.e_ar.e_rawstrtab = s;
e->e_u.e_ar.e_rawstrtabsz = sz;
sz = LIBELF_ADJUST_AR_SIZE(sz);
s += sz;
}
}
} else if (strncmp(arh.ar_name, LIBELF_AR_BSD_SYMTAB_NAME,
sizeof(LIBELF_AR_BSD_SYMTAB_NAME) - 1) == 0) {
/*
* BSD style archive symbol table.
*/
s += sizeof(arh);
e->e_u.e_ar.e_rawsymtab = s;
e->e_u.e_ar.e_rawsymtabsz = sz;
sz = LIBELF_ADJUST_AR_SIZE(sz);
s += sz;
}
/*
* Update the 'next' offset, so that a subsequent elf_begin()
* works as expected.
*/
e->e_u.e_ar.e_next = (off_t) (s - e->e_rawfile);
return (e);
error:
LIBELF_SET_ERROR(ARCHIVE, 0);
return (NULL);
}
+100
Переглянути файл
@@ -0,0 +1,100 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <gelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: libelf_checksum.c 189 2008-07-20 10:38:08Z jkoshy $");
static unsigned long
_libelf_sum(unsigned long c, const unsigned char *s, size_t size)
{
if (s == NULL || size == 0)
return (c);
while (size--)
c += *s++;
return (c);
}
unsigned long
_libelf_checksum(Elf *e, int elfclass)
{
size_t shn;
Elf_Scn *scn;
Elf_Data *d;
unsigned long checksum;
GElf_Ehdr eh;
GElf_Shdr shdr;
if (e == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0L);
}
if (e->e_class != elfclass) {
LIBELF_SET_ERROR(CLASS, 0);
return (0L);
}
if (gelf_getehdr(e, &eh) == NULL)
return (0);
/*
* Iterate over all sections in the ELF file, computing the
* checksum along the way.
*
* The first section is always SHN_UNDEF and can be skipped.
* Non-allocatable sections are skipped, as are sections that
* could be affected by utilities such as strip(1).
*/
checksum = 0;
for (shn = 1; shn < e->e_u.e_elf.e_nscn; shn++) {
if ((scn = elf_getscn(e, shn)) == NULL)
return (0);
if (gelf_getshdr(scn, &shdr) == NULL)
return (0);
if ((shdr.sh_flags & SHF_ALLOC) == 0 ||
shdr.sh_type == SHT_DYNAMIC ||
shdr.sh_type == SHT_DYNSYM)
continue;
d = NULL;
while ((d = elf_rawdata(scn, d)) != NULL)
checksum = _libelf_sum(checksum,
(unsigned char *) d->d_buf, d->d_size);
}
/*
* Return a 16-bit checksum compatible with Solaris.
*/
return (((checksum >> 16) & 0xFFFFUL) + (checksum & 0xFFFFUL));
}
Різницю між файлами не показано, бо вона завелика Завантажити різницю
+114
Переглянути файл
@@ -0,0 +1,114 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: libelf_data.c 1264 2010-11-12 14:53:23Z jkoshy $");
int
_libelf_xlate_shtype(uint32_t sht)
{
switch (sht) {
case SHT_DYNAMIC:
return (ELF_T_DYN);
case SHT_DYNSYM:
return (ELF_T_SYM);
#if defined(SHT_FINI_ARRAY)
case SHT_FINI_ARRAY:
return (ELF_T_ADDR);
#endif
#if defined(SHT_GNU_HASH)
case SHT_GNU_HASH:
return (ELF_T_GNUHASH);
#endif
#if defined(SHT_GNU_LIBLIST)
case SHT_GNU_LIBLIST:
return (ELF_T_WORD);
#endif
#if defined(SHT_GROUP)
case SHT_GROUP:
return (ELF_T_WORD);
#endif
case SHT_HASH:
return (ELF_T_WORD);
#if defined(SHT_INIT_ARRAY)
case SHT_INIT_ARRAY:
return (ELF_T_ADDR);
#endif
case SHT_NOBITS:
return (ELF_T_BYTE);
case SHT_NOTE:
return (ELF_T_NOTE);
#if defined(SHT_PREINIT_ARRAY)
case SHT_PREINIT_ARRAY:
return (ELF_T_ADDR);
#endif
case SHT_PROGBITS:
return (ELF_T_BYTE);
case SHT_REL:
return (ELF_T_REL);
case SHT_RELA:
return (ELF_T_RELA);
case SHT_STRTAB:
return (ELF_T_BYTE);
case SHT_SYMTAB:
return (ELF_T_SYM);
#if defined(SHT_SYMTAB_SHNDX)
case SHT_SYMTAB_SHNDX:
return (ELF_T_WORD);
#endif
#if defined(SHT_SUNW_dof)
case SHT_SUNW_dof:
return (ELF_T_BYTE);
#endif
#if defined(SHT_SUNW_move)
case SHT_SUNW_move:
return (ELF_T_MOVE);
#endif
#if defined(SHT_SUNW_syminfo)
case SHT_SUNW_syminfo:
return (ELF_T_SYMINFO);
#endif
#if defined(SHT_SUNW_verdef)
case SHT_SUNW_verdef: /* == SHT_GNU_verdef */
return (ELF_T_VDEF);
#endif
#if defined(SHT_SUNW_verneed)
case SHT_SUNW_verneed: /* == SHT_GNU_verneed */
return (ELF_T_VNEED);
#endif
#if defined(SHT_SUNW_versym)
case SHT_SUNW_versym: /* == SHT_GNU_versym */
return (ELF_T_HALF);
#endif
default:
return (-1);
}
}
+211
Переглянути файл
@@ -0,0 +1,211 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <gelf.h>
#include <libelf.h>
#include <stdlib.h>
#include <string.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: libelf_ehdr.c 1677 2011-07-28 04:35:53Z jkoshy $");
/*
* Retrieve counts for sections, phdrs and the section string table index
* from section header #0 of the ELF object.
*/
static int
_libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum,
uint16_t strndx)
{
Elf_Scn *scn;
size_t fsz;
int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap);
uint32_t shtype;
assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn));
fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, 1);
assert(fsz > 0);
if (e->e_rawsize < shoff + fsz) { /* raw file too small */
LIBELF_SET_ERROR(HEADER, 0);
return (0);
}
if ((scn = _libelf_allocate_scn(e, (size_t) 0)) == NULL)
return (0);
xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec);
(*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr),
e->e_rawfile + shoff, (size_t) 1,
e->e_byteorder != LIBELF_PRIVATE(byteorder));
#define GET_SHDR_MEMBER(M) ((ec == ELFCLASS32) ? scn->s_shdr.s_shdr32.M : \
scn->s_shdr.s_shdr64.M)
if ((shtype = GET_SHDR_MEMBER(sh_type)) != SHT_NULL) {
LIBELF_SET_ERROR(SECTION, 0);
return (0);
}
e->e_u.e_elf.e_nscn = GET_SHDR_MEMBER(sh_size);
e->e_u.e_elf.e_nphdr = (phnum != PN_XNUM) ? phnum :
GET_SHDR_MEMBER(sh_info);
e->e_u.e_elf.e_strndx = (strndx != SHN_XINDEX) ? strndx :
GET_SHDR_MEMBER(sh_link);
#undef GET_SHDR_MEMBER
return (1);
}
#define EHDR_INIT(E,SZ) do { \
Elf##SZ##_Ehdr *eh = (E); \
eh->e_ident[EI_MAG0] = ELFMAG0; \
eh->e_ident[EI_MAG1] = ELFMAG1; \
eh->e_ident[EI_MAG2] = ELFMAG2; \
eh->e_ident[EI_MAG3] = ELFMAG3; \
eh->e_ident[EI_CLASS] = ELFCLASS##SZ; \
eh->e_ident[EI_DATA] = ELFDATANONE; \
eh->e_ident[EI_VERSION] = LIBELF_PRIVATE(version); \
eh->e_machine = EM_NONE; \
eh->e_type = ELF_K_NONE; \
eh->e_version = LIBELF_PRIVATE(version); \
} while (0)
void *
_libelf_ehdr(Elf *e, int ec, int allocate)
{
void *ehdr;
size_t fsz, msz;
uint16_t phnum, shnum, strndx;
uint64_t shoff;
int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap);
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (e == NULL || e->e_kind != ELF_K_ELF) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if (e->e_class != ELFCLASSNONE && e->e_class != ec) {
LIBELF_SET_ERROR(CLASS, 0);
return (NULL);
}
if (e->e_version != EV_CURRENT) {
LIBELF_SET_ERROR(VERSION, 0);
return (NULL);
}
if (e->e_class == ELFCLASSNONE)
e->e_class = ec;
if (ec == ELFCLASS32)
ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr32;
else
ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr64;
if (ehdr != NULL) /* already have a translated ehdr */
return (ehdr);
fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1);
assert(fsz > 0);
// If we have a file that is attached to a read/write elf
// or the elf is a read only elf and the size is smaller than the
// file, then error.
if ((e->e_cmd == ELF_C_READ || (e->e_cmd == ELF_C_RDWR && e->e_rawfile)) && e->e_rawsize < fsz) {
LIBELF_SET_ERROR(HEADER, 0);
return (NULL);
}
msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT);
assert(msz > 0);
if ((ehdr = e->e_mem.alloc(msz)) == NULL) {
LIBELF_SET_ERROR(RESOURCE, 0);
return (NULL);
}
memset(ehdr, 0, msz);
if (ec == ELFCLASS32) {
e->e_u.e_elf.e_ehdr.e_ehdr32 = ehdr;
EHDR_INIT(ehdr,32);
} else {
e->e_u.e_elf.e_ehdr.e_ehdr64 = ehdr;
EHDR_INIT(ehdr,64);
}
if (allocate)
e->e_flags |= ELF_F_DIRTY;
// If there is no raw file, return as we are done and don't need to
// process the file on the disk.
if (!e->e_rawfile)
return (ehdr);
xlator = _libelf_get_translator(ELF_T_EHDR, ELF_TOMEMORY, ec);
(*xlator)(ehdr, msz, e->e_rawfile, (size_t) 1,
e->e_byteorder != LIBELF_PRIVATE(byteorder));
/*
* If extended numbering is being used, read the correct
* number of sections and program header entries.
*/
if (ec == ELFCLASS32) {
phnum = ((Elf32_Ehdr *) ehdr)->e_phnum;
shnum = ((Elf32_Ehdr *) ehdr)->e_shnum;
shoff = ((Elf32_Ehdr *) ehdr)->e_shoff;
strndx = ((Elf32_Ehdr *) ehdr)->e_shstrndx;
} else {
phnum = ((Elf64_Ehdr *) ehdr)->e_phnum;
shnum = ((Elf64_Ehdr *) ehdr)->e_shnum;
shoff = ((Elf64_Ehdr *) ehdr)->e_shoff;
strndx = ((Elf64_Ehdr *) ehdr)->e_shstrndx;
}
if (shnum >= SHN_LORESERVE ||
(shoff == 0LL && (shnum != 0 || phnum == PN_XNUM ||
strndx == SHN_XINDEX))) {
LIBELF_SET_ERROR(HEADER, 0);
return (NULL);
}
if (shnum != 0 || shoff == 0LL) { /* not using extended numbering */
e->e_u.e_elf.e_nphdr = phnum;
e->e_u.e_elf.e_nscn = shnum;
e->e_u.e_elf.e_strndx = strndx;
} else if (_libelf_load_extended(e, ec, shoff, phnum, strndx) == 0)
return (NULL);
return (ehdr);
}
+135
Переглянути файл
@@ -0,0 +1,135 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: libelf_extended.c 1360 2011-01-08 08:27:41Z jkoshy $");
/*
* Retrieve section #0, allocating a new section if needed.
*/
static Elf_Scn *
_libelf_getscn0(Elf *e)
{
Elf_Scn *s;
if ((s = STAILQ_FIRST(&e->e_u.e_elf.e_scn)) != NULL)
return (s);
return (_libelf_allocate_scn(e, (size_t) SHN_UNDEF));
}
int
_libelf_setshnum(Elf *e, void *eh, int ec, size_t shnum)
{
Elf_Scn *scn;
if (shnum >= SHN_LORESERVE) {
if ((scn = _libelf_getscn0(e)) == NULL)
return (0);
assert(scn->s_ndx == SHN_UNDEF);
if (ec == ELFCLASS32)
scn->s_shdr.s_shdr32.sh_size = shnum;
else
scn->s_shdr.s_shdr64.sh_size = shnum;
(void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
shnum = 0;
}
if (ec == ELFCLASS32)
((Elf32_Ehdr *) eh)->e_shnum = shnum;
else
((Elf64_Ehdr *) eh)->e_shnum = shnum;
return (1);
}
int
_libelf_setshstrndx(Elf *e, void *eh, int ec, size_t shstrndx)
{
Elf_Scn *scn;
if (shstrndx >= SHN_LORESERVE) {
if ((scn = _libelf_getscn0(e)) == NULL)
return (0);
assert(scn->s_ndx == SHN_UNDEF);
if (ec == ELFCLASS32)
scn->s_shdr.s_shdr32.sh_link = shstrndx;
else
scn->s_shdr.s_shdr64.sh_link = shstrndx;
(void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
shstrndx = SHN_XINDEX;
}
if (ec == ELFCLASS32)
((Elf32_Ehdr *) eh)->e_shstrndx = shstrndx;
else
((Elf64_Ehdr *) eh)->e_shstrndx = shstrndx;
return (1);
}
int
_libelf_setphnum(Elf *e, void *eh, int ec, size_t phnum)
{
Elf_Scn *scn;
if (phnum >= PN_XNUM) {
if ((scn = _libelf_getscn0(e)) == NULL)
return (0);
assert(scn->s_ndx == SHN_UNDEF);
if (ec == ELFCLASS32)
scn->s_shdr.s_shdr32.sh_info = phnum;
else
scn->s_shdr.s_shdr64.sh_info = phnum;
(void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
phnum = PN_XNUM;
}
if (ec == ELFCLASS32)
((Elf32_Ehdr *) eh)->e_phnum = phnum;
else
((Elf64_Ehdr *) eh)->e_phnum = phnum;
return (1);
}
+147
Переглянути файл
@@ -0,0 +1,147 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: libelf_fsize.m4 320 2009-03-07 16:37:53Z jkoshy $");
/* WARNING: GENERATED FROM libelf_fsize.m4. */
/*
* Create an array of file sizes from the elf_type definitions
*/
struct fsize {
size_t fsz32;
size_t fsz64;
};
static struct fsize fsize[ELF_T_NUM] = {
#if defined(__GNUC__)
#if LIBELF_CONFIG_ADDR
[ELF_T_ADDR] = { .fsz32 = sizeof(Elf32_Addr), .fsz64 = sizeof(Elf64_Addr) },
#endif
#if LIBELF_CONFIG_BYTE
[ELF_T_BYTE] = { .fsz32 = 1, .fsz64 = 1 },
#endif
#if LIBELF_CONFIG_CAP
[ELF_T_CAP] = { .fsz32 = sizeof(Elf32_Word)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+0 },
#endif
#if LIBELF_CONFIG_DYN
[ELF_T_DYN] = { .fsz32 = sizeof(Elf32_Sword)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Sxword)+sizeof(Elf64_Xword)+0 },
#endif
#if LIBELF_CONFIG_EHDR
[ELF_T_EHDR] = { .fsz32 = EI_NIDENT+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Word)+sizeof(Elf32_Addr)+sizeof(Elf32_Off)+sizeof(Elf32_Off)+sizeof(Elf32_Word)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+0, .fsz64 = EI_NIDENT+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Word)+sizeof(Elf64_Addr)+sizeof(Elf64_Off)+sizeof(Elf64_Off)+sizeof(Elf64_Word)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+0 },
#endif
#if LIBELF_CONFIG_GNUHASH
[ELF_T_GNUHASH] = { .fsz32 = 1, .fsz64 = 1 },
#endif
#if LIBELF_CONFIG_HALF
[ELF_T_HALF] = { .fsz32 = sizeof(Elf32_Half), .fsz64 = sizeof(Elf64_Half) },
#endif
#if LIBELF_CONFIG_LWORD
[ELF_T_LWORD] = { .fsz32 = sizeof(Elf32_Lword), .fsz64 = sizeof(Elf64_Lword) },
#endif
#if LIBELF_CONFIG_MOVE
[ELF_T_MOVE] = { .fsz32 = sizeof(Elf32_Lword)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+0, .fsz64 = sizeof(Elf64_Lword)+sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+0 },
#endif
#if LIBELF_CONFIG_MOVEP
[ELF_T_MOVEP] = { .fsz32 = 0, .fsz64 = 0 },
#endif
#if LIBELF_CONFIG_NOTE
[ELF_T_NOTE] = { .fsz32 = 1, .fsz64 = 1 },
#endif
#if LIBELF_CONFIG_OFF
[ELF_T_OFF] = { .fsz32 = sizeof(Elf32_Off), .fsz64 = sizeof(Elf64_Off) },
#endif
#if LIBELF_CONFIG_PHDR
[ELF_T_PHDR] = { .fsz32 = sizeof(Elf32_Word)+sizeof(Elf32_Off)+sizeof(Elf32_Addr)+sizeof(Elf32_Addr)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Word)+sizeof(Elf64_Word)+sizeof(Elf64_Off)+sizeof(Elf64_Addr)+sizeof(Elf64_Addr)+sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+0 },
#endif
#if LIBELF_CONFIG_REL
[ELF_T_REL] = { .fsz32 = sizeof(Elf32_Addr)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Addr)+sizeof(Elf64_Xword)+0 },
#endif
#if LIBELF_CONFIG_RELA
[ELF_T_RELA] = { .fsz32 = sizeof(Elf32_Addr)+sizeof(Elf32_Word)+sizeof(Elf32_Sword)+0, .fsz64 = sizeof(Elf64_Addr)+sizeof(Elf64_Xword)+sizeof(Elf64_Sxword)+0 },
#endif
#if LIBELF_CONFIG_SHDR
[ELF_T_SHDR] = { .fsz32 = sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Addr)+sizeof(Elf32_Off)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Word)+sizeof(Elf64_Word)+sizeof(Elf64_Xword)+sizeof(Elf64_Addr)+sizeof(Elf64_Off)+sizeof(Elf64_Xword)+sizeof(Elf64_Word)+sizeof(Elf64_Word)+sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+0 },
#endif
#if LIBELF_CONFIG_SWORD
[ELF_T_SWORD] = { .fsz32 = sizeof(Elf32_Sword), .fsz64 = sizeof(Elf64_Sword) },
#endif
#if LIBELF_CONFIG_SXWORD
[ELF_T_SXWORD] = { .fsz32 = 0, .fsz64 = sizeof(Elf64_Sxword) },
#endif
#if LIBELF_CONFIG_SYMINFO
[ELF_T_SYMINFO] = { .fsz32 = sizeof(Elf32_Half)+sizeof(Elf32_Half)+0, .fsz64 = sizeof(Elf64_Half)+sizeof(Elf64_Half)+0 },
#endif
#if LIBELF_CONFIG_SYM
[ELF_T_SYM] = { .fsz32 = sizeof(Elf32_Word)+sizeof(Elf32_Addr)+sizeof(Elf32_Word)+1+1+sizeof(Elf32_Half)+0, .fsz64 = sizeof(Elf64_Word)+1+1+sizeof(Elf64_Half)+sizeof(Elf64_Addr)+sizeof(Elf64_Xword)+0 },
#endif
#if LIBELF_CONFIG_VDEF
[ELF_T_VDEF] = { .fsz32 = sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Word)+sizeof(Elf64_Word)+sizeof(Elf64_Word)+0 },
#endif
#if LIBELF_CONFIG_VNEED
[ELF_T_VNEED] = { .fsz32 = sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Word)+sizeof(Elf64_Word)+sizeof(Elf64_Word)+0 },
#endif
#if LIBELF_CONFIG_WORD
[ELF_T_WORD] = { .fsz32 = sizeof(Elf32_Word), .fsz64 = sizeof(Elf64_Word) },
#endif
#if LIBELF_CONFIG_XWORD
[ELF_T_XWORD] = { .fsz32 = 0, .fsz64 = sizeof(Elf64_Xword) },
#endif
#elif defined(_MSC_VER)
{4, 8}, {1, 1}, {0, 0}, {8, 16}, {52, 64},
{2, 2}, {0, 0}, {0, 0}, {0, 0}, {1, 1},
{4, 8}, {32, 56}, {8, 16}, {12, 24}, {40, 64},
{4, 4}, {0, 8}, {0, 0}, {16, 24}, {20, 20},
{16, 16}, {4, 4}, {0, 8}, {1, 1}
#else
#error
#endif
};
size_t
_libelf_fsize(Elf_Type t, int ec, unsigned int v, size_t c)
{
size_t sz;
sz = 0;
if (v != EV_CURRENT)
LIBELF_SET_ERROR(VERSION, 0);
else if ((int) t < ELF_T_FIRST || t > ELF_T_LAST)
LIBELF_SET_ERROR(ARGUMENT, 0);
else {
sz = ec == ELFCLASS64 ? fsize[t].fsz64 : fsize[t].fsz32;
if (sz == 0)
LIBELF_SET_ERROR(UNIMPL, 0);
}
return (sz*c);
}
+145
Переглянути файл
@@ -0,0 +1,145 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <libelf.h>
#include <string.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: libelf_msize.m4 311 2009-02-26 16:46:31Z jkoshy $");
/* WARNING: GENERATED FROM libelf_msize.m4. */
struct msize {
size_t msz32;
size_t msz64;
};
static struct msize msize[ELF_T_NUM] = {
#if defined(__GNUC__)
#if LIBELF_CONFIG_ADDR
[ELF_T_ADDR] = { .msz32 = sizeof(Elf32_Addr), .msz64 = sizeof(Elf64_Addr) },
#endif
#if LIBELF_CONFIG_BYTE
[ELF_T_BYTE] = { .msz32 = 1, .msz64 = 1 },
#endif
#if LIBELF_CONFIG_CAP
[ELF_T_CAP] = { .msz32 = sizeof(Elf32_Cap), .msz64 = sizeof(Elf64_Cap) },
#endif
#if LIBELF_CONFIG_DYN
[ELF_T_DYN] = { .msz32 = sizeof(Elf32_Dyn), .msz64 = sizeof(Elf64_Dyn) },
#endif
#if LIBELF_CONFIG_EHDR
[ELF_T_EHDR] = { .msz32 = sizeof(Elf32_Ehdr), .msz64 = sizeof(Elf64_Ehdr) },
#endif
#if LIBELF_CONFIG_GNUHASH
[ELF_T_GNUHASH] = { .msz32 = 1, .msz64 = 1 },
#endif
#if LIBELF_CONFIG_HALF
[ELF_T_HALF] = { .msz32 = sizeof(Elf32_Half), .msz64 = sizeof(Elf64_Half) },
#endif
#if LIBELF_CONFIG_LWORD
[ELF_T_LWORD] = { .msz32 = sizeof(Elf32_Lword), .msz64 = sizeof(Elf64_Lword) },
#endif
#if LIBELF_CONFIG_MOVE
[ELF_T_MOVE] = { .msz32 = sizeof(Elf32_Move), .msz64 = sizeof(Elf64_Move) },
#endif
#if LIBELF_CONFIG_MOVEP
[ELF_T_MOVEP] = { .msz32 = 0, .msz64 = 0 },
#endif
#if LIBELF_CONFIG_NOTE
[ELF_T_NOTE] = { .msz32 = 1, .msz64 = 1 },
#endif
#if LIBELF_CONFIG_OFF
[ELF_T_OFF] = { .msz32 = sizeof(Elf32_Off), .msz64 = sizeof(Elf64_Off) },
#endif
#if LIBELF_CONFIG_PHDR
[ELF_T_PHDR] = { .msz32 = sizeof(Elf32_Phdr), .msz64 = sizeof(Elf64_Phdr) },
#endif
#if LIBELF_CONFIG_REL
[ELF_T_REL] = { .msz32 = sizeof(Elf32_Rel), .msz64 = sizeof(Elf64_Rel) },
#endif
#if LIBELF_CONFIG_RELA
[ELF_T_RELA] = { .msz32 = sizeof(Elf32_Rela), .msz64 = sizeof(Elf64_Rela) },
#endif
#if LIBELF_CONFIG_SHDR
[ELF_T_SHDR] = { .msz32 = sizeof(Elf32_Shdr), .msz64 = sizeof(Elf64_Shdr) },
#endif
#if LIBELF_CONFIG_SWORD
[ELF_T_SWORD] = { .msz32 = sizeof(Elf32_Sword), .msz64 = sizeof(Elf64_Sword) },
#endif
#if LIBELF_CONFIG_SXWORD
[ELF_T_SXWORD] = { .msz32 = 0, .msz64 = sizeof(Elf64_Sxword) },
#endif
#if LIBELF_CONFIG_SYMINFO
[ELF_T_SYMINFO] = { .msz32 = sizeof(Elf32_Syminfo), .msz64 = sizeof(Elf64_Syminfo) },
#endif
#if LIBELF_CONFIG_SYM
[ELF_T_SYM] = { .msz32 = sizeof(Elf32_Sym), .msz64 = sizeof(Elf64_Sym) },
#endif
#if LIBELF_CONFIG_VDEF
[ELF_T_VDEF] = { .msz32 = sizeof(Elf32_Verdef), .msz64 = sizeof(Elf64_Verdef) },
#endif
#if LIBELF_CONFIG_VNEED
[ELF_T_VNEED] = { .msz32 = sizeof(Elf32_Verneed), .msz64 = sizeof(Elf64_Verneed) },
#endif
#if LIBELF_CONFIG_WORD
[ELF_T_WORD] = { .msz32 = sizeof(Elf32_Word), .msz64 = sizeof(Elf64_Word) },
#endif
#if LIBELF_CONFIG_XWORD
[ELF_T_XWORD] = { .msz32 = 0, .msz64 = sizeof(Elf64_Xword) },
#endif
#elif defined(_MSC_VER)
{4, 8}, {1, 1}, {0, 0}, {8, 16}, {52, 64},
{2, 2}, {0, 0}, {0, 0}, {0, 0}, {1, 1},
{4, 8}, {32, 56}, {8, 16}, {12, 24}, {40, 64},
{4, 4}, {0, 8}, {0, 0}, {16, 24}, {20, 20},
{16, 16}, {4, 4}, {0, 8}, {1, 1}
#else
#error
#endif
};
size_t
_libelf_msize(Elf_Type t, int elfclass, unsigned int version)
{
size_t sz;
assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64);
assert((signed) t >= ELF_T_FIRST && t <= ELF_T_LAST);
if (version != EV_CURRENT) {
LIBELF_SET_ERROR(VERSION, 0);
return (0);
}
sz = (elfclass == ELFCLASS32) ? msize[t].msz32 : msize[t].msz64;
return (sz);
}
+160
Переглянути файл
@@ -0,0 +1,160 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <gelf.h>
#include <libelf.h>
#include <stdlib.h>
#include <string.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: libelf_phdr.c 1677 2011-07-28 04:35:53Z jkoshy $");
void *
_libelf_getphdr(Elf *e, int ec)
{
size_t phnum, phentsize;
size_t fsz, msz;
uint64_t phoff;
Elf32_Ehdr *eh32;
Elf64_Ehdr *eh64;
void *ehdr, *phdr;
int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap);
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
if (e == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if ((phdr = (ec == ELFCLASS32 ?
(void *) e->e_u.e_elf.e_phdr.e_phdr32 :
(void *) e->e_u.e_elf.e_phdr.e_phdr64)) != NULL)
return (phdr);
/*
* Check the PHDR related fields in the EHDR for sanity.
*/
if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
return (NULL);
phnum = e->e_u.e_elf.e_nphdr;
if (ec == ELFCLASS32) {
eh32 = (Elf32_Ehdr *) ehdr;
phentsize = eh32->e_phentsize;
phoff = (uint64_t) eh32->e_phoff;
} else {
eh64 = (Elf64_Ehdr *) ehdr;
phentsize = eh64->e_phentsize;
phoff = (uint64_t) eh64->e_phoff;
}
fsz = gelf_fsize(e, ELF_T_PHDR, phnum, e->e_version);
assert(fsz > 0);
if ((uint64_t) e->e_rawsize < (phoff + fsz)) {
LIBELF_SET_ERROR(HEADER, 0);
return (NULL);
}
msz = _libelf_msize(ELF_T_PHDR, ec, EV_CURRENT);
assert(msz > 0);
if ((phdr = e->e_mem.alloc(phnum * msz)) == NULL) {
LIBELF_SET_ERROR(RESOURCE, 0);
return (NULL);
}
memset(phdr, 0, msz);
if (ec == ELFCLASS32)
e->e_u.e_elf.e_phdr.e_phdr32 = phdr;
else
e->e_u.e_elf.e_phdr.e_phdr64 = phdr;
xlator = _libelf_get_translator(ELF_T_PHDR, ELF_TOMEMORY, ec);
(*xlator)(phdr, phnum * msz, e->e_rawfile + phoff, phnum,
e->e_byteorder != LIBELF_PRIVATE(byteorder));
return (phdr);
}
void *
_libelf_newphdr(Elf *e, int ec, size_t count)
{
void *ehdr, *newphdr, *oldphdr;
size_t msz;
if (e == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) {
LIBELF_SET_ERROR(SEQUENCE, 0);
return (NULL);
}
assert(e->e_class == ec);
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
assert(e->e_version == EV_CURRENT);
msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version);
assert(msz > 0);
newphdr = NULL;
if (count > 0 && (newphdr = e->e_mem.alloc(count * msz)) == NULL) {
LIBELF_SET_ERROR(RESOURCE, 0);
return (NULL);
}
if (count > 0) {
memset(newphdr, 0, count * msz);
}
if (ec == ELFCLASS32) {
if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr32) != NULL)
e->e_mem.dealloc(oldphdr);
e->e_u.e_elf.e_phdr.e_phdr32 = (Elf32_Phdr *) newphdr;
} else {
if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr64) != NULL)
e->e_mem.dealloc(oldphdr);
e->e_u.e_elf.e_phdr.e_phdr64 = (Elf64_Phdr *) newphdr;
}
e->e_u.e_elf.e_nphdr = count;
elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY);
return (newphdr);
}
+56
Переглянути файл
@@ -0,0 +1,56 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <gelf.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: libelf_shdr.c 189 2008-07-20 10:38:08Z jkoshy $");
void *
_libelf_getshdr(Elf_Scn *s, int ec)
{
Elf *e;
if (s == NULL || (e = s->s_elf) == NULL ||
e->e_kind != ELF_K_ELF) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if (ec == ELFCLASSNONE)
ec = e->e_class;
if (ec != e->e_class) {
LIBELF_SET_ERROR(CLASS, 0);
return (NULL);
}
return ((void *) &s->s_shdr);
}
+150
Переглянути файл
@@ -0,0 +1,150 @@
/*-
* Copyright (c) 2006,2008 Joseph Koshy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <libelf.h>
#include "_libelf.h"
LIBELF_VCSID("$Id: libelf_xlate.c 316 2009-02-28 16:08:44Z jkoshy $");
/*
* Translate to/from the file representation of ELF objects.
*
* Translation could potentially involve the following
* transformations:
*
* - an endianness conversion,
* - a change of layout, as the file representation of ELF objects
* can differ from their in-memory representation.
* - a change in representation due to a layout version change.
*/
Elf_Data *
_libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding,
int elfclass, int direction)
{
int byteswap;
size_t cnt, dsz, fsz, msz;
uintptr_t sb, se, db, de;
if (encoding == ELFDATANONE)
encoding = LIBELF_PRIVATE(byteorder);
if ((encoding != ELFDATA2LSB && encoding != ELFDATA2MSB) ||
dst == NULL || src == NULL || dst == src) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64);
assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY);
if (dst->d_version != src->d_version) {
LIBELF_SET_ERROR(UNIMPL, 0);
return (NULL);
}
if (src->d_buf == NULL || dst->d_buf == NULL) {
LIBELF_SET_ERROR(DATA, 0);
return (NULL);
}
if ((int) src->d_type < 0 || src->d_type >= ELF_T_NUM) {
LIBELF_SET_ERROR(DATA, 0);
return (NULL);
}
if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize)
(src->d_type, (size_t) 1, src->d_version)) == 0)
return (NULL);
msz = _libelf_msize(src->d_type, elfclass, src->d_version);
assert(msz > 0);
if (src->d_size % (direction == ELF_TOMEMORY ? fsz : msz)) {
LIBELF_SET_ERROR(DATA, 0);
return (NULL);
}
/*
* Determine the number of objects that need to be converted, and
* the space required for the converted objects in the destination
* buffer.
*/
if (direction == ELF_TOMEMORY) {
cnt = src->d_size / fsz;
dsz = cnt * msz;
} else {
cnt = src->d_size / msz;
dsz = cnt * fsz;
}
if (dst->d_size < dsz) {
LIBELF_SET_ERROR(DATA, 0);
return (NULL);
}
sb = (uintptr_t) src->d_buf;
se = sb + src->d_size;
db = (uintptr_t) dst->d_buf;
de = db + dst->d_size;
/*
* Check for overlapping buffers. Note that db == sb is
* allowed.
*/
if (db != sb && de > sb && se > db) {
LIBELF_SET_ERROR(DATA, 0);
return (NULL);
}
if ((direction == ELF_TOMEMORY ? db : sb) %
_libelf_malign(src->d_type, elfclass)) {
LIBELF_SET_ERROR(DATA, 0);
return (NULL);
}
dst->d_type = src->d_type;
dst->d_size = dsz;
byteswap = encoding != LIBELF_PRIVATE(byteorder);
if (src->d_size == 0 ||
(db == sb && !byteswap && fsz == msz))
return (dst); /* nothing more to do */
if (!(_libelf_get_translator(src->d_type, direction, elfclass))
(dst->d_buf, dsz, src->d_buf, cnt, byteswap)) {
LIBELF_SET_ERROR(DATA, 0);
return (NULL);
}
return (dst);
}
+403
Переглянути файл
@@ -0,0 +1,403 @@
/*
************************************************************************************************************************
*
* Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
*
***********************************************************************************************************************/
//
// Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
//
#include "memfile.h"
#include <errno.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <algorithm>
#include <vector>
#include <cstring>
#if defined(__GNUC__)
#include <unistd.h>
#include <sys/mman.h>
#include <sys/sendfile.h>
#else
#include <io.h>
#if !defined(PROT_READ)
#define PROT_READ 0x0004 // FILE_MAP_READ
#endif
#if !defined(MAP_PRIVATE)
#define MAP_PRIVATE 0x0001 // FILE_MAP_COPY
#endif
#endif
// Allocation granularity
#define ALLOC_G 512
#define is_file(fd) ((fd) >= 0)
#if defined(_WIN32)
#define OPEN ::_open
#define READ(f, b, l) ::_read((f), (b), (unsigned int)(l))
#define WRITE(f, b, l) ::_write((f), (b), (unsigned int)(l))
#define CLOSE ::_close
#define LSEEK ::_lseek
#define FSTAT ::fstat
#define FTRUNC(f, l) ::_chsize((f), (long)(l))
#define MMAP ::w32_mmap
#define MUNMAP ::w32_munmap
#else
#define OPEN ::open
#define READ(f, b, l) ::read((f), (b), (size_t)(l))
#define WRITE ::write
#define CLOSE ::close
#define LSEEK ::lseek
#define FSTAT ::fstat
#define FTRUNC(f, l) ::ftruncate((f), (off_t)(l))
#define MMAP ::mmap
#define MUNMAP ::munmap
#endif
#if defined(_WIN32)
extern "C" void* w32_mmap(void* start, size_t length, int prot, int flags, int fd, unsigned offset);
extern "C" int w32_munmap(void* start, size_t length);
#endif
namespace amd {
// A structure which either maintains in memory file or uses a real file.
class memfile_t {
public:
memfile_t() : buf(nullptr), curp(nullptr), size(0) {}
bool reserve(size_t new_size) {
if (!new_size)
new_size = 1;
new_size = (new_size + ALLOC_G - 1) & ~(ALLOC_G - 1);
size_t pos = tell();
void *p = realloc(buf, new_size);
if (!p)
return false;
buf = p;
setpos(pos);
return true;
}
bool open(int oflag, int pmode)
{
size = 0;
buf = curp = nullptr;
return reserve(1);
}
off_t read(void *buffer, size_t count)
{
if (!buffer) {
errno = EINVAL;
return -1;
}
size_t pos = tell();
if (pos >= size)
return 0;
size_t ret = size - pos;
ret = std::min(ret, count);
memcpy(buffer, curp, ret);
advance(ret);
return (off_t)ret;
}
off_t write(const void *buffer, size_t count)
{
if (!buffer) {
errno = EINVAL;
return -1;
}
size_t pos = tell();
size_t new_size = std::max(pos + count, size);
if (new_size > size) {
if (!reserve(new_size))
return -1;
if (pos > size)
memset((char*)buf + size, 0, pos - size);
size = new_size;
}
memcpy(curp, buffer, count);
advance(count);
return (off_t)count;
}
int close() {
if (is_open()) {
free(buf);
buf = nullptr;
size = 0;
return 0;
}
errno = EBADF;
return -1;
}
off_t lseek(off_t offset, int origin)
{
switch (origin) {
default:
errno = EINVAL;
return -1;
case SEEK_SET:
break;
case SEEK_CUR:
offset += (off_t)tell();
break;
case SEEK_END:
offset += (off_t)size;
break;
}
if (offset < 0) {
errno = EOVERFLOW;
return -1;
}
setpos((size_t)offset);
return offset;
}
bool fstat(struct stat *buf) const
{
if (!is_open()) {
errno = EBADF;
return false;
}
memset(buf, 0, sizeof(struct stat));
buf->st_mode = S_IFREG;
buf->st_size = (off_t)size;
return true;
}
bool ftruncate(size_t len)
{
if (len > size) {
size_t pos = tell();
lseek(0, SEEK_END);
while(len--)
write("", 1u);
setpos(len);
} else {
reserve(len);
size = len;
}
return true;
}
bool is_open() const { return buf != nullptr; }
size_t tell() const { return size_t((char*)curp - (char*)buf); }
void* get() const { return buf; }
protected:
void setpos(size_t new_pos) { curp = (char*)buf + new_pos; }
void advance(off_t offset) { curp = (char*)curp + offset; }
void advance(size_t offset) { curp = (char*)curp + offset; }
private:
void* buf;
void* curp;
size_t size;
};
} // namespace amd
using namespace amd;
static std::vector<memfile_t> Files;
static size_t fd2idx(int fd)
{
return (unsigned)-fd - 2;
}
static int idx2fd(size_t idx)
{
return -(int)idx - 2;
}
static memfile_t* get_memfile(int fd)
{
if (fd >= -1) {
errno = EBADF;
return nullptr;
}
size_t fno = fd2idx(fd);
if (fno >= Files.size()) {
errno = EBADF;
return nullptr;
}
memfile_t &m = Files[fno];
if (!m.is_open()) {
errno = EBADF;
return nullptr;
}
return &m;
}
// Acts the same as open(), but path can be NULL, which is a request for in memory file
int mem_open(const char *path, int oflag, int pmode)
{
if (path && path[0]) // Filename provided, real file requested
return OPEN(path, oflag, pmode);
memfile_t m;
if (!m.open(oflag, pmode))
return -1;
for (size_t i = 0; i < Files.size(); ++i) {
if (!Files[i].is_open()) {
Files[i] = m;
return idx2fd(i);
}
}
Files.push_back(m);
return idx2fd(Files.size() - 1);
}
off_t mem_read(int fd, void *buffer, size_t count)
{
if (is_file(fd))
return READ(fd, buffer, count);
memfile_t *m = get_memfile(fd);
if (!m)
return -1;
return m->read(buffer, count);
}
off_t mem_write(int fd, const void *buffer, size_t count)
{
if (is_file(fd))
return WRITE(fd, buffer, count);
memfile_t *m = get_memfile(fd);
if (!m)
return -1;
return m->write(buffer, count);
}
int mem_close(int fd)
{
if (is_file(fd))
return CLOSE(fd);
memfile_t *m = get_memfile(fd);
if (!m)
return -1;
int ret = m->close();
if ((size_t)fd == (Files.size() - 1))
Files.pop_back();
return ret;
}
off_t mem_lseek(int fd, off_t offset, int origin)
{
if (is_file(fd))
return LSEEK(fd, offset, origin);
memfile_t *m = get_memfile(fd);
if (!m)
return -1;
return m->lseek(offset, origin);
}
int mem_fstat(int fd, struct stat *buf)
{
if (is_file(fd))
return FSTAT(fd, buf);
memfile_t *m = get_memfile(fd);
if (!m)
return -1;
return m->fstat(buf) ? 0 : -1;
}
int mem_ftruncate(int fd, size_t len)
{
if (is_file(fd))
return FTRUNC(fd, len);
memfile_t *m = get_memfile(fd);
if (!m)
return -1;
return m->ftruncate(len) ? 0 : -1;
}
off_t mem_sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
{
#if defined(__GNUC__)
if (is_file(in_fd) && is_file(out_fd))
return sendfile(out_fd, in_fd, offset, count);
#endif
off_t start = offset ? *offset : mem_lseek(in_fd, 0, SEEK_CUR);
struct stat sb;
if (mem_fstat(in_fd, &sb) == -1)
return -1;
if (start < 0 || sb.st_size <= start)
return 0;
count = std::min(count, (size_t)(sb.st_size - start));
void *in = mem_mmap(NULL, count, PROT_READ, MAP_PRIVATE, in_fd, start);
if ((void*)-1 == in)
return -1;
off_t written = mem_write(out_fd, in, count);
mem_munmap(in, count);
if (written < 0)
return -1;
if (offset) {
*offset += written;
} else {
if (mem_lseek(in_fd, written, SEEK_CUR) < 0)
return -1;
}
return written;
}
void* mem_mmap(void* start, size_t length, int prot, int flags, int fd, unsigned offset)
{
if (is_file(fd))
return MMAP(start, length, prot, flags, fd, offset);
memfile_t *m = get_memfile(fd);
if (!m)
return (void*)-1;
return (char*)m->get() + offset;
}
int mem_munmap(void* start, size_t length)
{
MUNMAP(start, length);
return 0;
}
+40
Переглянути файл
@@ -0,0 +1,40 @@
/*
************************************************************************************************************************
*
* Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
*
***********************************************************************************************************************/
//
// Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
//
#ifndef _MEMFILE_H
#define _MEMFILE_H
#include <sys/types.h>
#if !defined(_MSC_VER)
#include <sys/stat.h>
#endif
#if defined(__cplusplus)
extern "C" {
#endif
// Acts the same as open(), but path can be NULL, which is a request for in memory file
extern int mem_open(const char *path, int oflag, int pmode);
extern off_t mem_read(int fd, void *buffer, size_t count);
extern off_t mem_write(int fd, const void *buffer, size_t count);
extern int mem_close(int fd);
extern off_t mem_lseek(int fd, off_t offset, int origin);
extern int mem_fstat(int fd, struct stat *buf);
extern int mem_ftruncate(int fd, size_t len);
extern off_t mem_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
extern void* mem_mmap(void* start, size_t length, int prot, int flags, int fd, unsigned offset);
extern int mem_munmap(void* start, size_t length);
#if defined(__cplusplus)
}
#endif
#endif // !_MEMFILE_H
+15
Переглянути файл
@@ -0,0 +1,15 @@
/*
************************************************************************************************************************
*
* Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
*
***********************************************************************************************************************/
#ifdef __GNUC__
# define roundup(x, y) (__builtin_constant_p (y) && powerof2 (y) \
? (((x) + (y) - 1) & ~((y) - 1)) \
: ((((x) + ((y) - 1)) / (y)) * (y)))
#else
# define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
#endif
+92
Переглянути файл
@@ -0,0 +1,92 @@
##
#######################################################################################################################
#
# Copyright (c) 2025 Advanced Micro Devices, Inc. All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
#######################################################################################################################
cmake_minimum_required(VERSION 3.21)
project(PAL LANGUAGES CXX)
add_library(pal INTERFACE)
set_target_properties(pal PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
POSITION_INDEPENDENT_CODE TRUE
)
target_compile_features(pal INTERFACE cxx_std_20)
if (NOT PAL_CLIENT_INTERFACE_MAJOR_VERSION EQUAL 932)
message(WARNING "PAL: PAL_CLIENT_INTERFACE_MAJOR_VERSION ${PAL_CLIENT_INTERFACE_MAJOR_VERSION} not supported !!!")
endif()
target_link_libraries(pal
INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/pal.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/palCompilerDeps.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/palUtil.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/pal_uuid.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/cwpack.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/pal_lz4.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/addrlib.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/amdrdf.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/zstd.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/vam.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/UberTraceService.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/DriverUtilsService.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/dd_settings.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/SettingsRpcService2.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddRpcServer.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddNet.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddRpcShared.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddSocket.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/devdriver.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/dd_common.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddCommon.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddCore.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/dd_libyaml.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/mpack.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/metrohash.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/stb_sprintf.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddRpcClient.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddEventStreamer.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddEventClient.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddEventParser.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddEventServer.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddYaml.lib
SetupAPI.Lib
)
target_compile_definitions(pal
INTERFACE
PAL_CLIENT_INTERFACE_MAJOR_VERSION=932
GPUOPEN_CLIENT_INTERFACE_MAJOR_VERSION=42
PAL_BUILD_RDF=1
PAL_DEVELOPER_BUILD=0
PAL_KMT_BUILD=1
)
target_include_directories(pal
INTERFACE
inc
inc/core
inc/gpuUtil
inc/util
shared/inc
shared/devdriver/shared/legacy/inc
shared/devdriver/third_party/dd_crc32/inc
shared/metrohash/src
)
+21
Переглянути файл
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2025 Advanced Micro Devices, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+833
Переглянути файл
@@ -0,0 +1,833 @@
/*
***********************************************************************************************************************
*
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
**********************************************************************************************************************/
/**
***********************************************************************************************************************
* @file pal.h
* @brief Common include for the Platform Abstraction Library (PAL) interface. Defines common types, enums, etc.
***********************************************************************************************************************
*/
#pragma once
#include "palFormat.h"
#include "palSysUtil.h"
// Forward declarations of global types (must be done outside of Pal namespace).
#if (PAL_KMT_BUILD) && !defined(__unix__)
struct HMONITOR__;
struct HWND__;
#endif
#if PAL_KMT_BUILD
struct _SECURITY_ATTRIBUTES;
#endif
/// Library-wide namespace encapsulating all PAL entities.
namespace Pal
{
typedef Util::int8 int8; ///< 8-bit integer.
typedef Util::int16 int16; ///< 16-bit integer.
typedef Util::int32 int32; ///< 32-bit integer.
typedef Util::int64 int64; ///< 64-bit integer.
typedef Util::uint8 uint8; ///< Unsigned 8-bit integer.
typedef Util::uint16 uint16; ///< Unsigned 16-bit integer.
typedef Util::uint32 uint32; ///< Unsigned 32-bit integer.
typedef Util::uint64 uint64; ///< Unsigned 64-bit integer.
typedef Util::gpusize gpusize; ///< Used to specify GPU addresses and sizes of GPU allocations. This differs from
/// size_t since the GPU still uses 64-bit addresses on a 32-bit OS.
typedef Util::Result Result; ///< The PAL core and utility companion share the same result codes for convenience.
typedef Util::Rational Rational; ///< A ratio of two unsigned integers.
#if defined(_WIN32)
typedef HMONITOR__* OsDisplayHandle; ///< OsDisplayHandle corresponds to an HMONITOR on Windows.
typedef HWND__* OsWindowHandle; ///< OsWindowHandle corresponds to an HWND on Windows.
typedef void* OsExternalHandle; ///< OsExternalHandle corresponds to a generic HANDLE on Windows
typedef uint32 OsVideoSessionHandle; ///< OsVideoSessionHandle corresponds to a video session handle on Vulkan.
constexpr OsWindowHandle NullWindowHandle = nullptr; ///< Value representing a null or invalid window handle.
#elif defined(__unix__)
typedef void* OsDisplayHandle; ///< The Display Handle for Linux except X11 platform
typedef uint32 OsExternalHandle; ///< OsExternalHandle corresponds to a generic handle on linux
typedef uint32 OsVideoSessionHandle; ///< OsVideoSessionHandle corresponds to a video session handle on linux.
/// OsWindowHandle corresponds to a window on X-Windows or surface on Wayland.
union OsWindowHandle
{
void* pSurface; ///< Native surface handle in wayland is a pointer.
uint64 win; ///< Native window handle in X is a 32-bit integer (but stored here as 64 bit).
};
constexpr OsWindowHandle NullWindowHandle = {nullptr}; ///< Value representing a null or invalid window handle.
// don't check for the Linux Platform type; just compare the larger member of the union
inline bool operator==(const Pal::OsWindowHandle& lhs, const Pal::OsWindowHandle& rhs)
{ return (lhs.pSurface == rhs.pSurface); }
inline bool operator!=(const Pal::OsWindowHandle& lhs, const Pal::OsWindowHandle& rhs)
{ return (lhs.pSurface != rhs.pSurface); }
#else
#error "Unsupported OS platform detected!"
#endif
#if PAL_CLIENT_EXAMPLE
typedef void* AddrHandle; ///< Corresponds to an ADDR_HANDLE.
#endif
constexpr uint32 InvalidVidPnSourceId = ~0u; ///< In cases where PAL cannot abstract a Windows VidPnSourceId, this
/// represents an invalid value. (Note: zero is a valid value.)
constexpr uint32 MaxVertexBuffers = 32; ///< Maximum number of vertex buffers per pipeline.
constexpr uint32 MaxColorTargets = 8; ///< Maximum number of color targets.
constexpr uint32 MaxStreamOutTargets = 4; ///< Maximum number of stream output target buffers.
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION < 936
constexpr uint32 MaxDescriptorSets = 2; ///< Maximum number of descriptor sets.
#endif
constexpr uint32 MaxMsaaRasterizerSamples = 16; ///< Maximum number of MSAA samples supported by the rasterizer.
constexpr uint32 MaxAvailableEngines = 12; ///< Maximum number of engines for a particular engine type.
constexpr uint32 MaxNumPlanes = 3; ///< Maximum number of format planes.
constexpr uint64 InternalApiPsoHash = UINT64_MAX; ///< Default Hash for PAL internal pipelines.
/// Specifies a category of GPU engine. Each category corresponds directly to a hardware engine. There may be multiple
/// engines available for a given type; the available engines on a particular GPU can be queried via
/// Device::GetProperties, returned in DeviceProperties.engineProperties[].
enum EngineType : uint32
{
/// Corresponds to the graphics hardware engine (a.k.a. graphcis ring a.k.a 3D).
EngineTypeUniversal,
/// Corresponds to asynchronous compute engines (ACE).
EngineTypeCompute,
/// Corresponds to SDMA engines.
EngineTypeDma,
/// Virtual engine that only supports inserting sleeps, used for implementing frame-pacing.
EngineTypeTimer,
/// Number of engine types.
EngineTypeCount,
};
/// Specifies a category of GPU work. Each queue type only supports specific types of work. Determining which
/// QueueTypes are supported on which engines can be queried via IDevice::GetProperties, returned in
/// DeviceProperties.engineProperties[].
enum QueueType : uint32
{
/// Supports graphics commands (draws), compute commands (dispatches), and copy commands.
QueueTypeUniversal,
/// Supports compute commands (dispatches), and copy commands.
QueueTypeCompute,
/// Supports copy commands.
QueueTypeDma,
/// Virtual engine that only supports inserting sleeps, used for implementing frame pacing.
/// This is a software-only queue.
QueueTypeTimer,
/// Number of queue types.
QueueTypeCount,
};
/// Defines flags for describing which queues are supported.
enum QueueTypeSupport : uint32
{
SupportQueueTypeUniversal = (1 << static_cast<uint32>(QueueTypeUniversal)),
SupportQueueTypeCompute = (1 << static_cast<uint32>(QueueTypeCompute)),
SupportQueueTypeDma = (1 << static_cast<uint32>(QueueTypeDma)),
SupportQueueTypeTimer = (1 << static_cast<uint32>(QueueTypeTimer)),
};
// Many command buffers break down into multiple command streams targeting internal sub-engines. For example, Universal
// command buffers build a primary stream (DE) but may also build a second stream for async compute engine (ACE).
enum class SubEngineType : uint32
{
Primary = 0, // Subqueue that is the queue itself, rather than an ancillary queue.
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION >= 914
AsyncCompute = 1, // Auxiliary ACE subqueue, together with a primary subqueue forms a "ganged" submit.
ConstantEngine = 2, // CP constant update engine that runs in parallel with draw engine.
// Internal usage only.
#else
ConstantEngine = 1, // CP constant update engine that runs in parallel with draw engine.
AsyncCompute = 2, // Auxiliary ACE subqueue, together with a primary subqueue forms a "ganged" submit.
Pup = 3, // Subqueue that is the queue itself but for PUP-style packets, rather than an
// ancillary queue
#endif
Count,
};
/// Defines the execution priority for a queue, specified either at queue creation or via IQueue::SetExecutionPriority()
/// on platforms that support it. QueuePriority::Normal corresponds to the default priority.
enum class QueuePriority : uint32
{
Normal = 0, ///< Normal priority (default).
Idle = 1, ///< Idle, or low priority (lower than Normal).
Medium = 2, ///< Medium priority (higher than Normal).
High = 3, ///< High priority (higher than Normal).
Realtime = 4, ///< Real time priority (higher than Normal).
Count
};
/// Defines flags for describing which queue priority levels are supported.
enum QueuePrioritySupport : uint32
{
SupportQueuePriorityNormal = (1 << static_cast<uint32>(QueuePriority::Normal)),
SupportQueuePriorityIdle = (1 << static_cast<uint32>(QueuePriority::Idle)),
SupportQueuePriorityMedium = (1 << static_cast<uint32>(QueuePriority::Medium)),
SupportQueuePriorityHigh = (1 << static_cast<uint32>(QueuePriority::High)),
SupportQueuePriorityRealtime = (1 << static_cast<uint32>(QueuePriority::Realtime)),
};
/// Selects one of a few possible memory heaps accessible by a GPU.
enum GpuHeap : uint32
{
GpuHeapLocal = 0x0, ///< Local heap visible to the CPU.
GpuHeapInvisible = 0x1, ///< Local heap not visible to the CPU.
GpuHeapGartUswc = 0x2, ///< GPU-accessible uncached system memory.
GpuHeapGartCacheable = 0x3, ///< GPU-accessible cached system memory.
GpuHeapCount
};
/// Describes the desired access for a memory allocation.
enum GpuHeapAccess : uint32
{
GpuHeapAccessExplicit = 0x0, ///< Memory access is not known. Heaps will be explicitly defined.
GpuHeapAccessCpuNoAccess = 0x1, ///< Memory access from CPU not required.
GpuHeapAccessGpuMostly = 0x2, ///< Memory optimized for reads/writes from GPU and accessible from CPU.
GpuHeapAccessCpuReadMostly = 0x3, ///< Memory optimized for reads from CPU.
GpuHeapAccessCpuWriteMostly = 0x4, ///< Memory optimized for writes from CPU.
GpuHeapAccessCpuMostly = 0x5, ///< Memory optimized for read/writes from CPU.
GpuHeapAccessCount
};
#if defined(__unix__)
/// Describes possible handle types.
enum class HandleType : uint32
{
GemFlinkName = 0x0, ///< GEM flink name (needs DRM authentication, used by DRI2)
Kms = 0x1, ///< KMS handle which is used by all driver ioctls
DmaBufFd = 0x2, ///< DMA-buf fd handle
KmsNoImport = 0x3, ///< Deprecated in favour of and same behaviour as HandleTypeDmaBufFd, use that instead of this
};
#endif
/// Comparison function determines how a pass/fail condition is determined between two values. For depth/stencil
/// comparison, the first value comes from source data and the second value comes from destination data.
enum class CompareFunc : uint8
{
Never = 0x0,
Less = 0x1,
Equal = 0x2,
LessEqual = 0x3,
Greater = 0x4,
NotEqual = 0x5,
GreaterEqual = 0x6,
_Always = 0x7,
// Unfortunately for Linux clients, X.h includes a "#define Always 2" macro. Clients have their choice of either
// undefing Always before including this header or using _Always when dealing with PAL.
#ifndef Always
Always = _Always,
#endif
Count
};
/// Defines an offset into a 2D pixel region.
struct Offset2d
{
int32 x; ///< X offset.
int32 y; ///< Y offset.
};
/// Defines an offset into a 3D pixel region.
struct Offset3d
{
int32 x; ///< X offset.
int32 y; ///< Y offset.
int32 z; ///< Z offset.
};
/// Defines an floating-point offset into a 3D pixel region.
struct Offset3dFloat
{
float x; ///< X offset.
float y; ///< Y offset.
float z; ///< Z offset.
};
/// Defines a width and height for a 2D image region. The dimensions could be pixels, blocks, or bytes
/// depending on context, so be sure to check documentation for the PAL interface of interest to be sure you
/// get it right.
struct Extent2d
{
uint32 width; ///< Width of region.
uint32 height; ///< Height of region.
};
/// Defines a signed width and height, for a 2D image region. The dimensions could be pixels, blocks, or bytes
/// depending on context, so be sure to check documentation for the PAL interface of interest to be sure you
/// get it right.
struct SignedExtent2d
{
int32 width; ///< Width of region.
int32 height; ///< Height of region.
};
/// Defines a width, height, and depth for a 3D image region. The dimensions could be pixels, blocks, or bytes
/// depending on context, so be sure to check documentation for the PAL interface of interest to be sure you
/// get it right.
struct Extent3d
{
uint32 width; ///< Width of region.
uint32 height; ///< Height of region.
uint32 depth; ///< Depth of region.
};
constexpr bool operator==(const Extent3d& x, const Extent3d& y)
{
return (x.width == y.width) && (x.height == y.height) && (x.depth == y.depth);
}
constexpr bool operator!=(const Extent3d& x, const Extent3d& y) { return (x == y) == false; }
/// Defines a signed width, height, and depth for a 3D image region. The dimensions could be pixels, blocks, or bytes
/// depending on context, so be sure to check documentation for the PAL interface of interest to be sure you
/// get it right.
struct SignedExtent3d
{
int32 width; ///< Width of region.
int32 height; ///< Height of region.
int32 depth; ///< Depth of region.
};
/// Defines a floating-point width, height, and depth for a 3D image region. The dimensions could be pixels, blocks, or
/// bytes depending on context, so be sure to check documentation for the PAL interface of interest to be sure you
/// get it right.
struct Extent3dFloat
{
float width; ///< Width of region.
float height; ///< Height of region.
float depth; ///< Depth of region.
};
/// Defines a region in 1D space.
struct Range
{
int32 offset; ///< Starting position.
uint32 extent; ///< Region size.
};
/// Defines a rectangular region in 2D space.
struct Rect
{
Offset2d offset; ///< Top left corner.
Extent2d extent; ///< Rectangle width and height.
};
/// Defines a cubic region in 3D space.
struct Box
{
Offset3d offset; ///< Top left front corner.
Extent3d extent; ///< Box width, height and depth.
};
/// ShaderHash represents a 128-bit shader hash.
struct ShaderHash
{
uint64 lower; ///< Lower 64-bits of hash
uint64 upper; ///< Upper 64-bits of hash
};
/// PipelineHash represents a concatenated pair of 64-bit hashes.
struct PipelineHash
{
uint64 stable; ///< Lower 64-bits of hash. "Stable" portion, suitable for e.g. shader replacement use cases.
uint64 unique; ///< Upper 64-bits of hash. "Unique" portion, suitable for e.g. pipeline cache use cases.
};
/// Common shader pre and post compilation stats.
struct CommonShaderStats
{
uint32 numUsedVgprs; ///< Number of VGPRs used by this shader
uint32 numUsedSgprs; ///< Number of SGPRs used by this shader
uint32 ldsSizePerThreadGroup; ///< LDS size per thread group in bytes.
size_t ldsUsageSizeInBytes; ///< LDS usage by this shader.
size_t scratchMemUsageInBytes; ///< Amount of scratch mem used by this shader.
gpusize gpuVirtAddress; ///< Gpu mem address of shader ISA code.
union
{
struct
{
uint32 isWave32 : 1; ///< If set, specifies that the shader is compiled in wave32 mode.
uint32 reserved : 31; ///< Reserved for future use.
};
uint32 u32All; ///< Flags packed as a 32-bit uint.
} flags; ///< Shader compilation stat flags.
};
/// Per-thread stack sizes
struct CompilerStackSizes
{
uint32 backendSize; ///< Managed by compiler backend
uint32 frontendSize; ///< Managed by compiler frontend
};
///@{
/// Determines whether two ShaderHashes or PipelineHashes are equal.
///
/// @param [in] hash1 The first 128-bit shader hash or pipeline hash
/// @param [in] hash2 The second 128-bit shader hash or pipeline hash
///
/// @returns True if the hashes are equal.
constexpr bool ShaderHashesEqual(const ShaderHash hash1, const ShaderHash hash2)
{ return ((hash1.lower == hash2.lower) && (hash1.upper == hash2.upper)); }
constexpr bool operator==(const ShaderHash hash1, const ShaderHash hash2)
{ return ((hash1.lower == hash2.lower) && (hash1.upper == hash2.upper)); }
constexpr bool operator!=(const ShaderHash hash1, const ShaderHash hash2)
{ return ((hash1.lower != hash2.lower) || (hash1.upper != hash2.upper)); }
constexpr bool PipelineHashesEqual(const PipelineHash hash1, const PipelineHash hash2)
{ return ((hash1.stable == hash2.stable) && (hash1.unique == hash2.unique)); }
///@}
///@{
/// Determines whether the given ShaderHash or PipelineHash is non-zero.
///
/// @param [in] hash A 128-bit shader hash or pipeline hash
///
/// @returns True if the hash is non-zero.
constexpr bool ShaderHashIsNonzero(const ShaderHash hash) { return ((hash.upper | hash.lower) != 0); }
constexpr bool PipelineHashIsNonzero(const PipelineHash hash) { return ((hash.stable | hash.unique) != 0); }
///@}
/// Specifies the Display Output Post-Processing (DOPP) desktop texture information, which are provided by OpenGL via
/// interop. The DOPP is an OpenGL extension to allow its client to access the desktop texture directly without the
/// need of copying to system memory. This is only supported on Windows.
struct DoppDesktopInfo
{
gpusize gpuVirtAddr; ///< The VA of the dopp desktop texture. Set to 0 for the non-dopp resource.
uint32 vidPnSourceId; ///< Display source id of the dopp desktop texture.
};
/// Specifies the Direct Capture resource information. Direct Capture is an extension that allows to access on-screen
/// primary, motion vectors, depth, and camera matrix directly. This is only supported on Windows.
struct DirectCaptureInfo
{
uint32 vidPnSourceId; ///< VidPnSource ID of the on-screen primary.
union
{
struct
{
uint32 preflip : 1; ///< Requires pre-flip primary access
uint32 postflip : 1; ///< Requires post-flip primary access. A DirectCapture resource cannot
/// have pre-flip and post-flip access at the same time
uint32 accessDesktop : 1; ///< Requires acces to the desktop
uint32 shared : 1; ///< This resource will be shared between APIs
uint32 frameGenRatio : 4; ///< Frame generation ratio
uint32 paceGeneratedFrame : 1; ///< Requires pacing the generated frames
uint32 requiresDisplayDcc : 1; ///< Requires display dcc support
uint32 requestMotionVectors : 1; ///< Request DirectCapture access to motion vector data if available
uint32 requestDepth : 1; ///< Request DirectCapture access to depth data if available
uint32 requestCamera : 1; ///< Request DirectCapture access to camera matrix data if available
uint32 initMotionVectors : 1; ///< Initialize the DirectCapture resource to access motion vector data
uint32 initDepth : 1; ///< Initialize the DirectCapture resource to access depth data
uint32 initCamera : 1; ///< Initialize the DirectCapture resource to access camera matrix
uint32 requestHudLessImage : 1; ///< Request DirectCapture access to HUD less image if available
uint32 initHudLessImage : 1; ///< Initialize the DirectCapture resource to access HUD less image
uint32 reserved : 14;
};
uint32 u32All;
} usageFlags;
OsExternalHandle hNewFrameEvent; ///< Event to notify of a new frame available for pre-flip or post-flip access
OsExternalHandle hFatalErrorEvent; ///< Event to notify of a fatal error
};
/// Specifies parameters for opening a shared GPU resource from a non-PAL device or non-local process.
struct ExternalResourceOpenInfo
{
OsExternalHandle hExternalResource; ///< External GPU resource from another non-PAL device to open.
#if defined(__unix__)
HandleType handleType; ///< Type of the external GPU resource to be opened.
#endif
union
{
struct
{
uint32 ntHandle : 1; ///< The provided hExternalResource is an NT handle instead of a default
/// KMT handle.
uint32 androidHwBufHandle : 1; ///< The provided hExternalResource is android hardware buffer handle
/// instead of fd.
uint32 isDopp : 1; ///< This is a Dopp texture, doppDesktopInfo is in use.
uint32 isDirectCapture : 1; ///< This is a Direct Capture resource, directCaptureInfo is in use.
uint32 globalGpuVa : 1; ///< The GPU virtual address must be visible to all devices.
uint32 reserved : 27; ///< Reserved for future use.
};
uint32 u32All; ///< Flags packed as 32-bit uint.
} flags; ///< External resource open flags.
union
{
DoppDesktopInfo doppDesktopInfo; ///< The information of dopp desktop texture.
DirectCaptureInfo directCaptureInfo; ///< The information of direct capture resource.
};
};
/// Packed pixel display enumeration.
///
/// In the medical imaging market space, there are several 10-bit per component color and grayscale displays
/// available.In addition to being high precision, these displays tend to be very high resolution.For grayscale
/// displays,one method of getting high pixel resolution in 10b precision is a proprietary method called
/// "packed pixel".Each of these packed pixel formats packs two/three 10-bit luminance values into a single
/// R8G8B8 pixel.
///
/// Example Displays:
///
/// EIZO GS510
/// NEC MD21GS
/// TOTOKU ME55Xi2
/// FIMI 3/5MP
///
///
/// The enumerations are named in a way to describe the format of the packed pixels. Names for
/// formats with two or three pixels packed into a single word (corresponding to a simple RGB pixel)
/// follow this convention:
///
/// LLLLLL_RRRRRR (L=left pixel, R=right pixel) or
/// LLL_MMM_RRR (L=left pixel, M=middle pixel, R=right pixel)
///
/// The bit order for a pixel follows this convention:
///
/// (ColorBand)MSB(ColorBand)LSB
///
/// For example: G70B54 means that the MSBs are in 7-0 of the green channel, and the LSBs
/// are stored in bits 5-4.
///
enum class PackedPixelType : uint32
{
NotPacked = 0, ///< Pixels not packed, for standard color RGB8 monitor
SplitG70B54_R70B10, ///< 10-bit mono, split screen
SplitB70G10_R70G76, ///< 10-bit mono, split screen
G70B54_R70B10, ///< 10-bit mono, 2 adjacent pixels
B70R32_G70R76, ///< 10-bit mono, 2 adjacent pixels
B70R30_G70R74, ///< 12-bit mono, 2 adjacent pixels
B70_G70_R70, ///< 8-bit mono, 3 adjacent pixels
R70G76, ///< 10-bit mono, single pixel
G70B54, ///< 10-bit mono, single pixel
Native, ///< 10-bit color, without packing
};
/// Enumerates the logging priority levels supported by PAL.
enum class LogLevel : uint32
{
Debug = 0, ///< Debug messages
Verbose, ///< High frequency messages
Info, ///< Low frequency messages
Alert, ///< Warnings
Error, ///< Critical issues
Always ///< All messages
};
/// Enumerates all log categories explicitly defined by PAL
enum class LogCategory : uint64
{
Correctness = 0, ///< Application correctness
Performance, ///< Application performance
Internal, ///< Internal logging
Display, ///< Display Info
Count
};
/// String table used to register log categories
constexpr const char* LogCategoryTable[] =
{
"Correctness",
"Performance",
"Internal",
"Display"
};
/// Typedef for log category masks.
typedef uint64 LogCategoryMask;
/// Log category mask for messages related to application correctness
constexpr LogCategoryMask LogCategoryMaskCorrectness = (1 << static_cast<uint32>(LogCategory::Correctness));
/// Log category mask for messages related to application performance
constexpr LogCategoryMask LogCategoryMaskPerformance = (1 << static_cast<uint32>(LogCategory::Performance));
/// Log category mask for messages related to internal messages
constexpr LogCategoryMask LogCategoryMaskInternal = (1 << static_cast<uint32>(LogCategory::Internal));
/// Log category mask for messages related to display information (e.g. HDR format)
constexpr LogCategoryMask LogCategoryMaskDisplay = (1 << static_cast<uint32>(LogCategory::Display));
/// Defines the modes that the GPU Profiling layer can be enabled with. If the GpuProfilerMode is
/// GpuProfilerTraceEnabledTtv or GpuProfilerTraceEnabledRgp, then the GpuProfilerConfig_TraceModeMask is examined to
/// configure the trace type (spm, sqtt or both) requested.
enum GpuProfilerMode : uint32
{
GpuProfilerDisabled = 0, ///< Gpu Profiler is disabled.
GpuProfilerCounterAndTimingOnly = 1, ///< Traces are disabled but perf counter and timing operations are enabled.
GpuProfilerTraceEnabledTtv = 2, ///< Traces are output in format (.csv, .out) for Thread trace viewer.
GpuProfilerTraceEnabledRgp = 3, ///< Trace data is output as .rgp file for Radeon Gpu Profiler.
};
// Defines the trigger keys for capturing the GPU profiler.
typedef Util::KeyCode GpuProfilerCaptureTriggerKey;
#define PAL_EVENT_LOGGING_VERSION 528
/// This enumeration identifies the source/owner of a resource object, used for event logging.
enum ResourceOwner : uint32
{
ResourceOwnerApplication = 0, ///< The resource is owned by the application
ResourceOwnerPalClient = 1, ///< The resource is owned by the PAL client
ResourceOwnerPal = 2, ///< The resource is owned by PAL
ResourceOwnerUnknown = 3, ///< The resource owner is unknown
};
/// This enumeration lists the usage/category of a resource object to give context in event logging.
enum ResourceCategory : uint32
{
ResourceCategoryApplication = 0, ///< The resource is used by the application.
ResourceCategoryRpm = 1, ///< The resource is used by RPM
ResourceCategoryProfiling = 2, ///< The resource is used for profiling (e.g. SQTT, SPM, etc)
ResourceCategoryDebug = 3, ///< The resource is used for debug purposes
ResourceCategoryRayTracing = 4, ///< The resource is used for ray tracing
ResourceCategoryVideo = 5, ///< The resource is used for video encode/decode
ResourceCategoryMisc = 6, ///< Miscellaneous, resource doesn't fit in any of the above categories
ResourceCategoryUnknown = 7, ///< The resource category is unknown
};
/// Set of information about resource ownership and usage, used for event logging.
struct ResourceEventInfo
{
ResourceOwner owner; ///< Resource owner
ResourceCategory category; ///< Resource category
};
/// General purpose on/off/default tri-state enum.
enum class TriState : uint8
{
Default = 0, ///< Let implementation decide whether to enable or disable
Enable = 1, ///< Force enable
Disable = 2, ///< Force disable
Count
};
/// Defines the modes that the GPU Profiling layer can be enabled with.
/**
***********************************************************************************************************************
* @mainpage
*
* Introduction
* ------------
* The Platform Abstraction Library (PAL) provides hardware and OS abstractions for Radeon (GCN+) user-mode 3D graphics
* drivers. The level of abstraction is chosen to support performant driver implementations of several APIs while
* hiding the client from hardware and operating system details.
*
* PAL client drivers will have no HW-specific code; their responsibility is to translate API/DDI commands into PAL
* commands as efficiently as possible. This means that the client should be unaware of hardware registers, PM4
* commands, SP3 shaders, etc. However, PAL is an abstraction of AMD hardware only, so many things in the PAL interface
* have an obvious correlation to hardware features.
*
* PAL client drivers should have little OS-specific code. PAL and its companion utility collection provide
* OS abstractions for almost everything a client might need, but there are some cases where this is unavoidable:
*
* + Handling dynamic library infrastructure. I.e., the client has to implement DllMain() on Windows, etc.
* + OS-specific APIs or extensions. DX may have Windows-specific functionality in the core API, and Vulkan may
* export certain OS-specific features as extensions (like for presenting contents to the screen).
* + Single OS clients (e.g., DX) may choose to make OS-specific calls directly simply out of convenience with no down
* side.
*
*
* The following diagram illustrates the software stack when running a 3D application with a PAL-based UMD. Non-AMD
* components are in gray, UMD client code is blue, AMD static libs linked into the UMD are green, and the AMD KMD
* is in red.
*
* @image html swStack.png
*
* PAL is a relatively _thick_ abstraction layer, typically accounting for the majority of code (excluding SC) in any
* particular UMD built on PAL. The level of abstraction tends to be higher in areas where client APIs are similar,
* and lower (closer to hardware) in areas where client APIs diverge significantly. The overall philosophy is to share
* as much code as possible without impacting client driver performance. Our committed goal is that CPU-limited
* performance should be within 5% of what a native solution could achieve, and GPU-limited performance should be within
* 2%.
*
* PAL uses a C++ interface. The public interface is defined in .../pal/inc, and client must _only_ include headers
* from that directory. The interface is spread over many header files - typically one per class - in order to clarify
* dependencies and reduce build times. There are two sub-directories in .../pal/inc:
*
* + <b>.../pal/inc/core</b> - Defines the PAL Core (see @ref Overview).
* + <b>.../pal/inc/gpuUtil</b> - Defines the PAL GPU Utility Collection (see @ref GpuUtilOverview).
* + <b>.../pal/inc/util</b> - Defines the PAL Utility Collection (see @ref UtilOverview).
*
*
* @copydoc VersionHistory
*
* Next: @ref Build
***********************************************************************************************************************
*/
/**
***********************************************************************************************************************
* @page Overview PAL Core Overview
*
* ### Introduction
* PAL's core interface is defined in the @ref Pal namespace, and defines an object-oriented model for interacting with
* the GPU and OS. The interface closely resembles the Vulkan and DX12 APIs. Some common features of these
* APIs that are central to the PAL interface:
*
* - All shader stages, and some additional "shader adjacent" state, are glommed together into a monolithic pipeline
* object.
* - Explicit, free-threaded command buffer generation.
* - Support for multiple, asynchronous engines for executing GPU work (graphics, compute, DMA).
* - Explicit system and GPU memory management.
* - Flexible shader resource binding model.
* - Explicit management of stalls, cache flushes, and compression state changes.
*
* However, as a common component supporting multiple APIs, the PAL interface tends to be lower level in places where
* client APIs diverge.
*
* ### Settings
* The PAL library has a number of configuration settings available for the client to modify either programmatically
* or via external settings. PAL also includes infrastructure for building/loading client-specific settings.
* See @ref Settings for a detailed description of this support.
*
* ### Initialization
* The first step to interacting with the PAL core is creating an IPlatform object and enumerating IDevice objects
* representing GPUs attached to the system and, optionally, IScreen objects representing displays attached to the
* system. See @ref LibInit for a detailed description.
*
* ### System Memory Allocation
* Clients have a lot of control over PAL's system memory allocations. Most PAL objects require the client to provide
* system memory; the client first calls a GetSize() method and then passes a pointer to PAL on the actual create call.
* Further, when PAL needs to make an internal allocation, it will optionally call a client callback, which can be
* specified on platform creation. This callback will specify a category for the allocation, which may imply an
* expected lifetime.
*
* ### Interface Classes
* The following diagram illustrates the relationship of some key PAL interfaces and how they interact to render a
* typical frame in a modern game. Below that is a listing of all of PAL's interface classes, and a very brief
* description of their purpose. Follow the link for each interface to see detailed reference documentation.
*
* @image html scheduling.png
*
* - __OS Abstractions__
* + _IPlatform_: Root-level object created by clients that interact with PAL. Mostly responsible for enumerating
* devices and screens attached to the system and returning any system-wide properties.<br><br>
* + _IDevice_: Configurable context for querying properties of a particular GPU and interacting with it. Acts as a
* factory for almost all other PAL objects.<br><br>
* + _IQueue_: A device has one or more _engines_ which are able to issue certain types of work. Tahiti, for example,
* has 1 universal engine (supports graphics, compute, or copy commands), 2 compute engines (support
* compute or copy commands), and 2 DMA engines (support only copy commands). An IQueue object is a
* context for submitting work on a particular engine. This mainly takes the form of submitting command
* buffers and presenting images to the screen. Work performed in a queue will be started in order, but
* work executed on different queues (even if the queues reference the same engine) is not guaranteed
* to be ordered without explicit synchronization.<br><br>
* + _IQueueSemaphore_: Queue semaphores can be signaled and waited on from an IQueue in order to control execution
* order between queues.<br><br>
* + _IFence_: Used for coarse-grain CPU/GPU synchronization. Fences can be signalled from the GPU as part of a
* command buffer submission on a queue, then waited on from the CPU.<br><br>
* + _IGpuMemory_: Represents a GPU-accessible memory allocation. Can either be virtual (only VA allocation which
* must be explicitly mapped via an IQueue operation) or physical. Residency of physical allocations
* must be managed by the client either globally for a device (IDevice::AddGpuMemoryReferences) or by
* specifying allocations referenced by command buffers at submit.<br><br>
* + _ICmdAllocator_: GPU memory allocation pool used for backing an ICmdBuffer. The client is free to create one
* allocator per device, or one per thread to remove thread contention.<br><br>
* + _IScreen_: Represents a display attached to the system. Mostly used for managing full-screen flip
* presents.<br><br>
* + _IPrivateScreen_: Represents a display that is not otherwise visible to the OS, typically a VR head mounted
* display.<br><br>
* - __Hardware IP Abstractions__
* + __All IP__
* - _ICmdBuffer_: Clients build command buffers to execute the desired work on the GPU, and submit them on a
* corresponding queue. Different types of work can be executed depending on the _queueType_ of
* the command buffer (graphics work, compute work, DMA work).<br><br>
* - _IImage_: Images are a 1D, 2D, or 3D collection of pixels (i.e., _texture_) that can be accessed by the
* GPU in various ways: texture sampling, BLT source/destination, UAV, etc.<br><br>
* + __GFXIP-only__
* - _IShader_: Container for shader byte code used as an input to pipeline creation. No compilation occurs
* until an IPipeline is created. Currently, AMDIL is the only supported input language.<br><br>
* - _IPipeline_: Comprised of all shader stages (CS for compute, VS/HS/DS/GS/PS for graphics), resource mappings
* describing how user data entries are to be used by the shaders, and some other fixed-function
* state like depth/color formats, blend enable, MSAA enable, etc.<br><br>
* - _IColorTargetView_: IImage view allowing the image to be bound as a color target (i.e., RTV.).<br><br>
* - _IDepthStencilView_: IImage view allowing the image to be bound as a depth/stencil target (i.e., DSV).<br><br>
* - _IGpuEvent_: Used for fine-grained (intra-command buffer) synchronization between the CPU and GPU. GPU
* events can be set/reset from either the CPU or GPU and waited on from either.<br><br>
* - _IQueryPool_: Collection of query slots for tracking occlusion or pipeline stats query results.<br><br>
* - __Dynamic State Objects__: _IColorBlendState_, _IDepthStencilState_, _IMsaaState_, _IScissorState_,
* and _IViewportState_ define logical collections of related fixed function graphics
* state, similar to DX11.<br><br>
* - _IPerfExperiment_: Used for gathering performance counter and thread trace data.<br><br>
* - _IBorderColorPalette_: Provides a collection of indexable colors for use by samplers that clamp to an
* arbitrary border color.<br><br>
* - __Common Base Classes__
* + _IDestroyable_: Defines a _Destroy()_ method for the PAL interface. Calling _Destroy()_ will release any
* internally allocated resources for the object, but the client is still responsible for freeing
* the system memory provided for the object.<br><br>
* + _IGpuMemoryBindable_: Defines a set of methods for binding GPU memory to the object. Interfaces that inherit
* _IGpuMemoryBindable_ require GPU memory in order to be used by the GPU. The client
* must query the requirements (e.g., alignment, size, heaps) and allocate/bind GPU memory
* for the object. _IGpuMemoryBindable_ inherits from _IDestroyable_.<br><br>
*
* ### %Format Info
* Several helper methods are available for dealing with image formats in the @ref Formats namespace.
*
* ### Graphics/Compute Execution Model
* Most graphics/compute work is defined by first binding a set of states then issuing a draw or dispatch command to
* kick off the work. The complete set of graphics states available in PAL is illustrated below; compute is a subset
* of this that only includes the pipeline, user data entries, and border color palette.
*
* @image html stateBreakdown.jpg
*
* Most of these correspond directly to a PAL interface object above, and these items are bound by calling a
* corresponding _CmdBind...()_ method in the ICmdBuffer interface. The states marked in yellow and orange, however,
* are _immediate_ states for which there is no object, you just specify the required state values in the corresponding
* _CmdSet...()_ method in the ICmdBuffer interface.
*
* User data entries are the way that input resources are specified for the pipeline on an upcoming draw/dispatch. This
* mapping is complicated, and is described fully in @ref ResourceBinding.
*
* A final complication worth noting is that PAL provides no implicit surface synchronization. The client is
* responsible for explicitly inserting barriers to resolve data hazards, flush/invalidate caches, and ensure images
* are in the proper compression state. For more detail, see ICmdBuffer::CmdReleaseThenAcquire, CmdRelease, CmdAcquire,
* CmdReleaseEvent, CmdAcquireEvent and AcquireReleaseInfo.
*
***********************************************************************************************************************
*/
} // Pal
+204
Переглянути файл
@@ -0,0 +1,204 @@
/*
***********************************************************************************************************************
*
* Copyright (c) 2015-2025 Advanced Micro Devices, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
**********************************************************************************************************************/
/**
***********************************************************************************************************************
* @file palCmdAllocator.h
* @brief Defines the Platform Abstraction Library (PAL) ICmdAllocator interface and related types.
***********************************************************************************************************************
*/
#pragma once
#include "pal.h"
#include "palDestroyable.h"
namespace Pal
{
// Forward declarations.
struct GpuMemSubAllocInfo;
class IGpuMemory;
/// Flags controlling the creation of ICmdAllocator objects.
union CmdAllocatorCreateFlags
{
struct
{
uint32 threadSafe : 1; ///< If set, the allocator will acquire a lock each time it is accessed;
/// otherwise it will not attempt to protect itself from multithreaded
/// access.
uint32 autoMemoryReuse : 1; ///< If set, the allocator will track when the GPU finishes accessing
/// each piece of command memory and attempt to reuse memory which the
/// GPU is done with before allocating more memory from the OS. If not
/// set, memory will only be recycled after a call to
/// @ref ICmdAllocator::Reset().
uint32 disableBusyChunkTracking : 1; ///< If set, the allocator will not do any GPU-side tracking of which
/// command chunks are still in use. It will be the client's (or the
/// application's) responsibility to guarantee that command chunks are
/// not returned to the allocator before the GPU has finished processing
/// them. Failure to guarantee this will result in undefined behavior.
/// This flag has no effect if @ref autoMemoryReuse is not set.
uint32 autoTrimMemory : 1; ///< If set the allocator will automatically trim down the allocations
/// (where all chunks are idle on the freeList). A minimum of
/// allocFreeThreshold allocations are kept for fast reuse.
uint32 reserved : 28; ///< Reserved for future use.
};
uint32 u32All; ///< Flags packed as 32-bit uint.
};
/// Different type of allocation data that an ICmdAllocator allocates and distributes to command buffers.
enum CmdAllocType : uint32
{
CommandDataAlloc = 0, ///< Data allocated is for executable commands.
EmbeddedDataAlloc, ///< Data allocated is for embedded data.
LargeEmbeddedDataAlloc, ///< Data allocated is for embedded data, allocation is >32kb
GpuScratchMemAlloc, ///< Data allocated is GPU-only accessible at command buffer execution-time. Possible
/// uses like GPU events.
CmdAllocatorTypeCount ///< Number of allocation types for ICmdAllocator's.
};
/// Specifies properties for creation of an ICmdAllocator object. Input structure to IDevice::CreateCmdAllocator().
struct CmdAllocatorCreateInfo
{
CmdAllocatorCreateFlags flags; ///< Flags controlling command allocator creation.
struct
{
GpuHeap allocHeap; ///< Preferred allocation heap. For @ref GpuScratchMemAlloc, this field is
/// ignored and the allocation will always be in GPU-invisible memory. For
/// all other allocation types, this must be CPU-mappable.
/// For best performance, command allocators that will be used by the
/// UVD engine should prefer the Local heap
gpusize allocSize; ///< Size, in bytes, of the GPU memory allocations this allocator will create.
/// It must be an integer multiple of suballocSize.
gpusize suballocSize; ///< Size, in bytes, of the chunks of GPU memory this allocator will give to
/// command buffers. It must be an integer multiple of 4096.
/// Must be greater than zero even if the client doesn't plan on using this
/// allocation type.
uint32 allocFreeThreshold; ///< Minimum count of free allocations that the allocator should keep around
/// for fast reuse. It is used when the autoTrimMemory flag is set.
} allocInfo[CmdAllocatorTypeCount]; ///< Information for each allocation type.
};
/// Output structure for QueryUtilizationInfo().
/// The CmdAllocator utilization data can be queried by PAL clients in order to decide whether to trim the allocations.
struct CmdAllocatorUtilizationInfo
{
uint32 numAllocations; ///< Number of allocations owned by the allocator.
uint32 numFreeChunks; ///< Number of chunks that are reset and not in use.
uint32 numBusyChunks; ///< Number of chunks that in use by the GPU.
uint32 numReuseChunks; ///< Number of chunks that have been 'returned' to the allocator for reuse.
};
/**
***********************************************************************************************************************
* @interface ICmdAllocator
* @brief Allocates and distributes GPU memory to command buffers on the client's behalf.
*
* All ICmdBuffer objects must be associated with an ICmdAllocator at creation. Command buffers may switch command
* allocators when ICmdBuffer::Reset() is called. The set of command buffers associated with a given command allocator
* will query that allocator for additional GPU memory as they are building commands.
*
* To protect against race conditions the client must ask for a thread safe command allocator unless its can guarantee
* that all command buffers associated with a given command allocator will be built, reset, and destroyed in a thread-
* safe manner. It is illegal to destroy a command allocator while it still has command buffers associated with it.
*
* @see IDevice::CreateCmdAllocator()
***********************************************************************************************************************
*/
class ICmdAllocator : public IDestroyable
{
public:
/// Explicitly resets a command allocator, marking all internal GPU memory allocations as unused.
///
/// The client is responsible for guaranteeing that all command buffers associated with this allocator have finished
/// GPU execution and have been explicitly reset before calling this function.
///
/// @param [in] freeMemory If the all GPU and CPU memory allocations should be returned to the OS.
///
/// @returns Success if the command allocator was successfully reset. Otherwise, one of the following errors may be
/// returned:
/// + ErrorUnknown if an internal PAL error occurs.
virtual Result Reset(bool freeMemory) = 0;
/// Explicitly trims a command allocator, deleting as many unused internal GPU memory allocations as possible.
///
/// @returns Success if the command allocator was successfully trimmed.
///
/// @param [in] allocTypeMask Gives control whether trimming will be applied for each CmdAllocType.
/// Use (1 << CmdAllocatorTypeCount) - 1 to apply trimming to all types.
/// When trimming only the embedded date use (1 << EmbeddedDataAlloc).
/// @param [in] dynamicThreshold Minimum count of free allocations that the allocator should keep around
virtual Result Trim(uint32 allocTypeMask, uint32 dynamicThreshold) = 0;
/// Query the numbers of allocations and chunks of the given CmdAllocator type.
/// This may help clients to decide whether they may apply trimming or not.
///
/// @returns Success if valid values can be reported.
///
/// @param [in] type CmdAllocType that is being queried
/// @param [out] pUtilizationInfo The allocation and chunk counts will be stored here.
virtual Result QueryUtilizationInfo(CmdAllocType type, CmdAllocatorUtilizationInfo* pUtilizationInfo) const = 0;
/// Returns the value of the associated arbitrary client data pointer.
/// Can be used to associate arbitrary data with a particular PAL object.
///
/// @returns Pointer to client data.
void* GetClientData() const
{
return m_pClientData;
}
/// Sets the value of the associated arbitrary client data pointer.
/// Can be used to associate arbitrary data with a particular PAL object.
///
/// @param [in] pClientData A pointer to arbitrary client data.
void SetClientData(
void* pClientData)
{
m_pClientData = pClientData;
}
protected:
/// @internal Constructor. Prevent use of new operator on this interface. Client must create objects by explicitly
/// called the proper create method.
ICmdAllocator() : m_pClientData(nullptr) {}
/// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by
/// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the
/// object on their own.
virtual ~ICmdAllocator() { }
private:
/// @internal Client data pointer. This can have an arbitrary value and can be returned by calling GetClientData()
/// and set via SetClientData().
/// For non-top-layer objects, this will point to the layer above the current object.
void* m_pClientData;
};
} // Pal
Різницю між файлами не показано, бо вона завелика Завантажити різницю
+370
Переглянути файл
@@ -0,0 +1,370 @@
/*
***********************************************************************************************************************
*
* Copyright (c) 2025 Advanced Micro Devices, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
**********************************************************************************************************************/
/**
***********************************************************************************************************************
* @file palCmdTracking.h
* @brief Defines a number of support classes used for construction and storage of struct TrackedCmdLocation
* defined in trackedCmdLocation.h
*
* - struct TrackingEventInfo: A single from uint8 to name, used for logging
* - class TrackedCmdSupportBase A set of TrackingEventInfo, maintained outside of Pal
* - class TrackedCmdLocationArray The arrays for TrackedCmdLocation's used for reporting
* correlation data through ICmdBufferReporting::CorrelationReportOnSubmit
***********************************************************************************************************************
*/
#pragma once
#include "pal.h"
#include "palVector.h"
#include "trackedCmdLocation.h"
namespace Pal
{
// forward decl
class Platform;
namespace CmdDisassembly
{
// forward definition
class TrackedCmdLocationArray;
/**
************************************************************************************************************************
* @brief class TrackedCmdLocationRef
* A copyable reference to a member in a TrackedCmdLocationArray, invariant to that array be
* re-allocated.
*
* @detail Is simply a pointer to a TrackedCmdLocationArray, and an index in to that array
*
************************************************************************************************************************
*/
class TrackedCmdLocationRef
{
public:
TrackedCmdLocationRef()
: m_pSourceArray(nullptr),
m_index(0)
{
}
TrackedCmdLocationRef(
TrackedCmdLocationArray* pSourceArray,
Util::uint32 index)
: m_pSourceArray(pSourceArray),
m_index(index)
{
}
TrackedCmdLocationRef(
TrackedCmdLocationRef&& other) = default;
TrackedCmdLocationRef(
TrackedCmdLocationRef const& other) = default;
TrackedCmdLocationRef& operator=(
TrackedCmdLocationRef&& other) = default;
TrackedCmdLocationRef& operator=(
TrackedCmdLocationRef const& other) = default;
bool operator==(
TrackedCmdLocationRef const& other) const
{ return (this->m_pSourceArray == other.m_pSourceArray) && (this->m_index == other.m_index); }
bool operator!=(
TrackedCmdLocationRef const& other) const
{ return (this->m_pSourceArray != other.m_pSourceArray) || (this->m_index != other.m_index); }
TrackedCmdLocation* Use();
const TrackedCmdLocation* Get() const;
Util::uint32 GetIndex() const
{
return m_index;
}
/// Helper functions
///
/// Clears the TrackedCmdLocation referred to by this TrackedCmdLocationRef
///
/// @returns
/// Result::ErrorInvalidPointer if (IsValid() == false)
/// Result::Success if successful
Result Clear();
/// @returns
/// TrackedCmdLocationMode::Invalid if (IsValid() == false)
/// Get()->m_mode otherwise
TrackedCmdLocationMode GetMode() const;
/// Sets the TrackedCmdLocation referred to by this TrackedCmdLocationRef
/// to mode TrackedCmdLocationMode::Before
///
/// @param [in] eventId Refers to an uint8 event that has a begin and/or an end associated with it
/// Most likely, a value registered to a TrackedCmdSupportBase
/// @param [in] beforePtr The end pointer for the cmdList being tracked before the event referred to by eventId
/// Only 48-bits of beforePtr are used
///
/// @returns
/// Result::ErrorInvalidPointer if (IsValid() == false)
/// Result::Success if successful
Result SetAsBefore(
uint8 eventId,
uint64 beforePtr);
/// Sets the TrackedCmdLocation referred to by this TrackedCmdLocationRef
/// to mode TrackedCmdLocationMode::After
///
/// @param [in] eventId Refers to an uint8 event that has a begin and/or an end associated with it
/// Most likely, a value registered to a TrackedCmdSupportBase
/// @param [in] afterPtr The end pointer for the cmdList being tracked after the event referred to by eventId
/// Only 48-bits of afterPtr are used
///
/// @returns
/// Result::ErrorInvalidPointer if (IsValid() == false)
/// Result::Success if successful
Result SetAsAfter(
uint8 eventId,
uint64 afterPtr);
/// Sets the TrackedCmdLocation referred to by this TrackedCmdLocationRef
/// to mode TrackedCmdLocationMode::Delta, with no begin or end (ie, no data can be written to
/// the cmdList being tracked "during" the event referred to be eventId
///
/// @param [in] eventId Refers to an uint8 event that does not have a begin and/or an end associated with it
/// Such as Pal::CmdDisassembly::TrackedCmdLocation::PostClientEvent
/// @param [in] ptr The end pointer for the cmdList being tracked after the event referred to by eventId
/// Only 48-bits of ptr are used
///
/// @returns
/// Result::ErrorInvalidPointer if (IsValid() == false)
/// Result::Success if successful
Result SetAsEmptyDelta(
uint8 eventId,
uint64 ptr);
/// Sets the TrackedCmdLocation referred to by this TrackedCmdLocationRef
/// to mode TrackedCmdLocationMode::ClientId
///
/// @param [in] clientId A 61-bit bit value used by the client application to identify which cmdList is being
/// tracked
///
/// @returns
/// Result::ErrorInvalidPointer if (IsValid() == false)
/// Result::Success if successful
Result SetAsClientId(
uint64 clientId);
/// Sets the TrackedCmdLocation referred to by this TrackedCmdLocationRef
/// to mode TrackedCmdLocationMode::ClientEventId
///
/// @param [in] clientEventId A 61-bit bit value used by the client application to identify
/// a client event relative to the current end position of the cmdList being tracked
///
/// @returns
/// Result::ErrorInvalidPointer if (IsValid() == false)
/// Result::Success if successful
Result SetAsClientEvent(
uint64 clientEventId);
/// @brief bool TrackedCmdLocation::TrySetAsDelta(uint64 afterPtr)
/// Will attempt to set this TrackedCmdLocation to type TrackedCmdLocationMode::Delta
///
/// @detail If GetMode() == TrackedCmdLocationMode::Before and afterPtr - m_correlateInternal.m_ptr is small
/// enough to be encoded in m_correlateInternal.m_deltaInDWords, the mode will be altered to
/// TrackedCmdLocationMode::Delta, with afterPtr - m_correlateInternal.m_ptr encoded in
/// m_correlateInternal.m_deltaInDWords.
/// If this attempt fails, the calling function should instead create a TrackedCmdLocationMode::After
/// TrackedCmdLocation
///
/// @param [in] afterPtr, the value a TrackedCmdLocationMode::After would have for m_correlateInternal.m_ptr
/// @return Result::Success if it was possible to set this TrackedCmdLocation to type
/// TrackedCmdLocationMode::Delta
/// Result::Unsupported if the conditions described above are not met.
Result TrySetAsDelta(
uint64 afterPtr);
private:
TrackedCmdLocationArray* m_pSourceArray;
Util::uint32 m_index;
Result SetMode(
TrackedCmdLocationMode mode);
};
/// @brief struct TrackingEventInfo
/// Essentially just a name, plus a boolean to indicate whether the name is valid / has been set
struct TrackingEventInfo
{
Util::StringView<char> name;
bool isValid;
TrackingEventInfo()
: isValid(false)
{}
};
/**
************************************************************************************************************************
* @brief class TrackedCmdSupportBase translates eventId's to strings for internal correlation events
*
* @detail For use in Pal::Queue when dumping to text files. Corresponds to
* TrackedCmdLocation::m_correlateInternal.m_event for the cases where TrackedCmdLocation::m_mode
* is not TrackedCmdLocationMode::ClientEvent
*
* The implementation for this is in whatever client of Pal that is creating the internal correlation events,
*
************************************************************************************************************************
*/
class TrackedCmdSupportBase
{
public:
virtual ~TrackedCmdSupportBase() = default;
void SetEventIdName(
uint8 eventId,
const char* name)
{
PAL_ASSERT(static_cast<uint32>(eventId) < NumUInt8Values);
m_allEventsMap[eventId].name = name;
m_allEventsMap[eventId].isValid = true;
}
TrackingEventInfo const& GetEventInfo(
uint8 eventId) const
{
PAL_ASSERT(static_cast<uint32>(eventId) < NumUInt8Values);
return m_allEventsMap[eventId];
}
protected:
static constexpr uint32 NumUInt8Values = UINT8_MAX + 1;
TrackingEventInfo m_allEventsMap[NumUInt8Values];
TrackedCmdSupportBase() = default;
};
/**
************************************************************************************************************************
* @brief class TrackedCmdLocationArray is simple a TrackedCmdLocationVec together with a clientId
* and some helpers. TrackedCmdLocationArray live on Pal::GfxCmdBuffer
*
* @detail Each Pal::GfxCmdBuffer has at most CmdDisassembly::MaxNumSubCmdBuffers TrackedCmdLocationArray's
* corresponding to Pal::GfxCmdBuffer::NumCmdStreams();
*
* The clientId used for TrackedCmdLocationArray::m_clientId, corresponds to the client Id used in
* TrackedCmdLocation::m_clientId.m_clientId
*
* For the moment, the underlying implementation used is
* Util::Vector<TrackedCmdLocation, DefaultCapacity, Pal::Platform>, but could be changed to use a Chunk
* scheme, especially as sizes of cmdLists can become very large.
* The only requirement to a change, is for TrackedCmdLocationRef continues to function as an accessor
*
* Note that the functions in TrackedCmdLocationArray are not designed for thread-safety, as they are
* issued from command-list-building functions that are, in their turn, not thread safe. Adding mutex
* behavior here would potentially hide issues relating to thread-safety.
*
************************************************************************************************************************
*/
class TrackedCmdLocationArray
{
public:
static constexpr uint32 DefaultCapacity = 1024;
static constexpr uint32 BadIndex = UINT32_MAX;
static constexpr uint64 InvalidClientId = UINT64_MAX;
typedef Util::Vector<TrackedCmdLocation, DefaultCapacity, Pal::Platform> TrackedCmdLocationVec;
static uint32 GetTrackedCmdLocationArraySizeInBytes()
{
return sizeof(TrackedCmdLocationArray);
}
static TrackedCmdLocationArray* CreateTrackedCmdLocationArray(
void* pMemory,
Pal::Platform* pPlatform);
void Reset()
{
m_lastLocation = TrackedCmdLocationRef(this, BadIndex);
m_clientId = InvalidClientId;
m_locations.Clear();
}
void Destroy();
uint64 GetClientId() const
{
return m_clientId;
}
Result SetClientId(
uint64 clientId);
Util::uint32 GetTotalSize() const
{
return m_locations.size();
}
const TrackedCmdLocationVec& GetLocationsVec() const
{
return m_locations;
}
TrackedCmdLocationVec& UseLocationsVec()
{
return m_locations;
}
Pal::Result MakeNext(
TrackedCmdLocationRef* pResult);
const TrackedCmdLocationRef GetLast() const
{
return m_lastLocation;
}
bool IsLast(
TrackedCmdLocationRef const& location) const
{
return location == m_lastLocation;
}
private:
TrackedCmdLocationVec m_locations;
Pal::Platform* m_pPlatform;
uint64 m_clientId;
TrackedCmdLocationRef m_lastLocation;
TrackedCmdLocationArray(
Pal::Platform* pPlatform);
~TrackedCmdLocationArray() = default;
};
} // namespace CmdDisassembly
} // namespace Pal
+70
Переглянути файл
@@ -0,0 +1,70 @@
/*
***********************************************************************************************************************
*
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
**********************************************************************************************************************/
/**
***********************************************************************************************************************
* @file palDestroyable.h
* @brief Defines the Platform Abstraction Library (PAL) IDestroyable interface.
***********************************************************************************************************************
*/
#pragma once
namespace Pal
{
/**
***********************************************************************************************************************
* @interface IDestroyable
* @brief Interface inherited by objects that must be explicitly destroyed by the client.
*
* This includes all objects except:
*
* + @ref IColorTargetView, @ref IDepthStencilView - These classes are treated as SRDs by the DX12 runtime. Therefore,
* PAL guarantees that no action needs to be taken at Destroy() - the client should just free the memory backing these
* classes.
* + @ref IDevice - These objects are created during IPlatform::EnumerateDevices() and are automatically destroyed
* along with the Platform object.
* + @ref IPrivateScreen - These objects are created as during IPlatform::EnumerateDevices() based on
* which screens are attached to each device. They are automatically destroyed along with the Platform object.
***********************************************************************************************************************
*/
class IDestroyable
{
public:
/// Frees all resources associated with this object.
///
/// It is the client's responsibility to only call this method once there are no more existing references to this
/// object. This method does not free the system memory associated with the object (as specified in pPlacementAddr
/// during creation); the client is responsible for freeing that memory since they allocated it.
virtual void Destroy() = 0;
protected:
/// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by
/// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the
/// object on their own.
virtual ~IDestroyable() { }
};
} // Pal

Деякі з файлів не показано, оскільки було змінено дуже багато файлів Показати більше