Migrate amdgpu-windows-interop to rocm-systems (#808)
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
/config.local
|
||||||
|
/tmp
|
||||||
|
/cache
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
[core]
|
||||||
|
autostage = true
|
||||||
|
remote = storage
|
||||||
|
['remote "storage"']
|
||||||
|
url = s3://therock-dvc/rocm-systems
|
||||||
|
allow_anonymous_login = true
|
||||||
@@ -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
|
||||||
@@ -62,6 +62,10 @@
|
|||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file: 'projects/roctracer/**/*'
|
- any-glob-to-any-file: 'projects/roctracer/**/*'
|
||||||
|
|
||||||
|
"shared: amdgpu-windows-interop":
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: 'shared/amdgpu-windows-interop/**/*'
|
||||||
|
|
||||||
documentation:
|
documentation:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file:
|
- 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
|
git clone --no-checkout --filter=blob:none https://github.com/ROCm/rocm-systems.git
|
||||||
cd rocm-systems
|
cd rocm-systems
|
||||||
git sparse-checkout init --cone
|
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
|
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:
|
If your work involves changing projects or introducing new projects, you can update your sparse-checkout environment:
|
||||||
|
|
||||||
```bash
|
```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.
|
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
|
## 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.
|
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.
|
||||||
|
|||||||
@@ -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 Security’s 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. AMD’s 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.
|
||||||
@@ -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)
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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()
|
||||||
@@ -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 */
|
||||||
+2618
File diff suppressed because it is too large
Load Diff
+47
@@ -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);
|
||||||
|
}'
|
||||||
|
|
||||||
+14
@@ -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
|
||||||
@@ -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 */
|
||||||
@@ -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
|
||||||
+19
@@ -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_ */
|
||||||
+355
@@ -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_
|
||||||
+13
@@ -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)
|
||||||
|
|
||||||
@@ -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.
|
||||||
|
|
||||||
@@ -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:
|
||||||
|
*;
|
||||||
|
};
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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];
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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));
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
+1264
File diff suppressed because it is too large
Load Diff
+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);
|
||||||
|
}
|
||||||
@@ -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_ */
|
||||||
@@ -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));
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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));
|
||||||
|
}
|
||||||
+3100
File diff suppressed because it is too large
Load Diff
+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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
|
)
|
||||||
@@ -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.
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||||
@@ -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
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user