Replace private libelf with elfio
Change-Id: I4c630d78f7bf23dda85ec8480bb2790864405657
Этот коммит содержится в:
@@ -119,7 +119,6 @@ option(BUILD_PAL "Build PAL backend" OFF)
|
||||
if (BUILD_PAL)
|
||||
add_subdirectory(device/pal)
|
||||
|
||||
add_definitions(-DAMD_LIBELF)
|
||||
add_subdirectory(compiler/sc/HSAIL)
|
||||
else ()
|
||||
add_subdirectory(device/rocm)
|
||||
@@ -127,8 +126,6 @@ endif()
|
||||
|
||||
set(COMGR_CPP device/comgrctx.cpp)
|
||||
|
||||
add_subdirectory(elf/utils/libelf)
|
||||
|
||||
set(oclruntime_src
|
||||
thread/thread.cpp
|
||||
thread/monitor.cpp
|
||||
@@ -161,13 +158,11 @@ set(oclruntime_src
|
||||
os/os_posix.cpp
|
||||
compiler/lib/utils/options.cpp
|
||||
elf/elf.cpp
|
||||
elf/elf_utils.cpp
|
||||
#${CMAKE_CURRENT_SOURCE_DIR}/compiler/tools/caching/cache.cpp
|
||||
)
|
||||
|
||||
add_library(amdrocclr_static STATIC
|
||||
${oclruntime_src} ${COMGR_CPP}
|
||||
$<TARGET_OBJECTS:oclelf_obj>)
|
||||
${oclruntime_src} ${COMGR_CPP})
|
||||
|
||||
set_target_properties(amdrocclr_static PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
@@ -180,17 +175,12 @@ target_include_directories(amdrocclr_static
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/compiler/lib/include>
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/compiler/lib>
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/compiler/lib/backends/common>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/elf/utils/common>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/elf/utils/libelf>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/elf>
|
||||
$<BUILD_INTERFACE:${OPENCL_DIR}>
|
||||
# GL and EGL headers.
|
||||
$<BUILD_INTERFACE:${OPENCL_DIR}/khronos/headers>
|
||||
$<BUILD_INTERFACE:${OPENCL_DIR}/khronos/headers/opencl2.2>
|
||||
$<TARGET_PROPERTY:amd_comgr,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
PRIVATE
|
||||
$<TARGET_PROPERTY:oclelf_obj,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||
|
||||
target_compile_definitions(amdrocclr_static PRIVATE BSD_LIBELF)
|
||||
$<TARGET_PROPERTY:amd_comgr,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||
|
||||
if(USE_COMGR_LIBRARY)
|
||||
# FIXME: This should not be part of the public interface. Downstream
|
||||
|
||||
@@ -554,7 +554,7 @@ bool ClBinary::setElfTarget() {
|
||||
static const uint32_t Target = 21;
|
||||
assert(((0xFFFF8000 & Target) == 0) && "ASIC target ID >= 2^15");
|
||||
uint16_t elf_target = static_cast<uint16_t>(0x7FFF & Target);
|
||||
return elfOut()->setTarget(elf_target, amd::OclElf::CAL_PLATFORM);
|
||||
return elfOut()->setTarget(elf_target, amd::Elf::CAL_PLATFORM);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -630,7 +630,7 @@ void ClBinary::init(amd::option::Options* optionsObj, bool amdilRequired) {
|
||||
}
|
||||
}
|
||||
|
||||
bool ClBinary::isRecompilable(std::string& llvmBinary, amd::OclElf::oclElfPlatform thePlatform) {
|
||||
bool ClBinary::isRecompilable(std::string& llvmBinary, amd::Elf::ElfPlatform thePlatform) {
|
||||
/* It is recompilable if there is llvmir that was generated for
|
||||
the same platform (CPU or GPU) and with the same bitness.
|
||||
|
||||
@@ -643,16 +643,16 @@ bool ClBinary::isRecompilable(std::string& llvmBinary, amd::OclElf::oclElfPlatfo
|
||||
}
|
||||
|
||||
uint16_t elf_target;
|
||||
amd::OclElf::oclElfPlatform platform;
|
||||
amd::Elf::ElfPlatform platform;
|
||||
if (elfIn()->getTarget(elf_target, platform)) {
|
||||
if (platform == thePlatform) {
|
||||
return true;
|
||||
}
|
||||
if ((platform == amd::OclElf::COMPLIB_PLATFORM) &&
|
||||
(((thePlatform == amd::OclElf::CAL_PLATFORM) &&
|
||||
if ((platform == amd::Elf::COMPLIB_PLATFORM) &&
|
||||
(((thePlatform == amd::Elf::CAL_PLATFORM) &&
|
||||
((elf_target == (uint16_t)EM_AMDIL) || (elf_target == (uint16_t)EM_HSAIL) ||
|
||||
(elf_target == (uint16_t)EM_HSAIL_64))) ||
|
||||
((thePlatform == amd::OclElf::CPU_PLATFORM) &&
|
||||
((thePlatform == amd::Elf::CPU_PLATFORM) &&
|
||||
((elf_target == (uint16_t)EM_386) || (elf_target == (uint16_t)EM_X86_64))))) {
|
||||
return true;
|
||||
}
|
||||
@@ -704,7 +704,7 @@ bool ClBinary::createElfBinary(bool doencrypt, Program::type_t type) {
|
||||
buildVerInfo.append("OpenCL 1.1" AMD_PLATFORM_INFO);
|
||||
}
|
||||
|
||||
elfOut_->addSection(amd::OclElf::COMMENT, buildVerInfo.data(), buildVerInfo.size());
|
||||
elfOut_->addSection(amd::Elf::COMMENT, buildVerInfo.data(), buildVerInfo.size());
|
||||
switch (type) {
|
||||
case Program::TYPE_NONE: {
|
||||
elfOut_->setType(ET_NONE);
|
||||
@@ -815,8 +815,8 @@ bool ClBinary::setElfIn() {
|
||||
if (binary_ == nullptr) {
|
||||
return false;
|
||||
}
|
||||
elfIn_ = new amd::OclElf(ELFCLASSNONE, binary_, size_, nullptr, ELF_C_READ);
|
||||
if ((elfIn_ == nullptr) || elfIn_->hasError()) {
|
||||
elfIn_ = new amd::Elf(ELFCLASSNONE, binary_, size_, nullptr, amd::Elf::ELF_C_READ);
|
||||
if ((elfIn_ == nullptr) || !elfIn_->isSuccessful()) {
|
||||
if (elfIn_) {
|
||||
delete elfIn_;
|
||||
elfIn_ = nullptr;
|
||||
@@ -836,8 +836,8 @@ void ClBinary::resetElfIn() {
|
||||
}
|
||||
|
||||
bool ClBinary::setElfOut(unsigned char eclass, const char* outFile) {
|
||||
elfOut_ = new amd::OclElf(eclass, nullptr, 0, outFile, ELF_C_WRITE);
|
||||
if ((elfOut_ == nullptr) || elfOut_->hasError()) {
|
||||
elfOut_ = new amd::Elf(eclass, nullptr, 0, outFile, amd::Elf::ELF_C_WRITE);
|
||||
if ((elfOut_ == nullptr) || !elfOut_->isSuccessful()) {
|
||||
if (elfOut_) {
|
||||
delete elfOut_;
|
||||
elfOut_ = nullptr;
|
||||
@@ -857,12 +857,12 @@ void ClBinary::resetElfOut() {
|
||||
}
|
||||
|
||||
bool ClBinary::loadLlvmBinary(std::string& llvmBinary,
|
||||
amd::OclElf::oclElfSections& elfSectionType) const {
|
||||
amd::Elf::ElfSections& elfSectionType) const {
|
||||
// Check if current binary already has LLVMIR
|
||||
char* section = nullptr;
|
||||
size_t sz = 0;
|
||||
const amd::OclElf::oclElfSections SectionTypes[] = {amd::OclElf::LLVMIR, amd::OclElf::SPIR,
|
||||
amd::OclElf::SPIRV};
|
||||
const amd::Elf::ElfSections SectionTypes[] = {amd::Elf::LLVMIR, amd::Elf::SPIR,
|
||||
amd::Elf::SPIRV};
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if (elfIn_->getSection(SectionTypes[i], §ion, &sz) && section && sz > 0) {
|
||||
@@ -880,7 +880,7 @@ bool ClBinary::loadCompileOptions(std::string& compileOptions) const {
|
||||
char* options = nullptr;
|
||||
size_t sz;
|
||||
compileOptions.clear();
|
||||
if (elfIn_->getSymbol(amd::OclElf::COMMENT, getBIFSymbol(symOpenclCompilerOptions).c_str(),
|
||||
if (elfIn_->getSymbol(amd::Elf::COMMENT, getBIFSymbol(symOpenclCompilerOptions).c_str(),
|
||||
&options, &sz)) {
|
||||
if (sz > 0) {
|
||||
compileOptions.append(options, sz);
|
||||
@@ -894,7 +894,7 @@ bool ClBinary::loadLinkOptions(std::string& linkOptions) const {
|
||||
char* options = nullptr;
|
||||
size_t sz;
|
||||
linkOptions.clear();
|
||||
if (elfIn_->getSymbol(amd::OclElf::COMMENT, getBIFSymbol(symOpenclLinkerOptions).c_str(),
|
||||
if (elfIn_->getSymbol(amd::Elf::COMMENT, getBIFSymbol(symOpenclLinkerOptions).c_str(),
|
||||
&options, &sz)) {
|
||||
if (sz > 0) {
|
||||
linkOptions.append(options, sz);
|
||||
@@ -905,21 +905,21 @@ bool ClBinary::loadLinkOptions(std::string& linkOptions) const {
|
||||
}
|
||||
|
||||
void ClBinary::storeCompileOptions(const std::string& compileOptions) {
|
||||
elfOut()->addSymbol(amd::OclElf::COMMENT, getBIFSymbol(symOpenclCompilerOptions).c_str(),
|
||||
elfOut()->addSymbol(amd::Elf::COMMENT, getBIFSymbol(symOpenclCompilerOptions).c_str(),
|
||||
compileOptions.c_str(), compileOptions.length());
|
||||
}
|
||||
|
||||
void ClBinary::storeLinkOptions(const std::string& linkOptions) {
|
||||
elfOut()->addSymbol(amd::OclElf::COMMENT, getBIFSymbol(symOpenclLinkerOptions).c_str(),
|
||||
elfOut()->addSymbol(amd::Elf::COMMENT, getBIFSymbol(symOpenclLinkerOptions).c_str(),
|
||||
linkOptions.c_str(), linkOptions.length());
|
||||
}
|
||||
|
||||
bool ClBinary::isSPIR() const {
|
||||
char* section = nullptr;
|
||||
size_t sz = 0;
|
||||
if (elfIn_->getSection(amd::OclElf::LLVMIR, §ion, &sz) && section && sz > 0) return false;
|
||||
if (elfIn_->getSection(amd::Elf::LLVMIR, §ion, &sz) && section && sz > 0) return false;
|
||||
|
||||
if (elfIn_->getSection(amd::OclElf::SPIR, §ion, &sz) && section && sz > 0) return true;
|
||||
if (elfIn_->getSection(amd::Elf::SPIR, §ion, &sz) && section && sz > 0) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -928,7 +928,7 @@ bool ClBinary::isSPIRV() const {
|
||||
char* section = nullptr;
|
||||
size_t sz = 0;
|
||||
|
||||
if (elfIn_->getSection(amd::OclElf::SPIRV, §ion, &sz) && section && sz > 0) {
|
||||
if (elfIn_->getSection(amd::Elf::SPIRV, §ion, &sz) && section && sz > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -887,11 +887,11 @@ class ClBinary : public amd::HeapObject {
|
||||
virtual bool setElfTarget();
|
||||
|
||||
// class used in for loading images in new format
|
||||
amd::OclElf* elfIn() { return elfIn_; }
|
||||
amd::Elf* elfIn() { return elfIn_; }
|
||||
|
||||
// classes used storing and loading images in new format
|
||||
amd::OclElf* elfOut() { return elfOut_; }
|
||||
void elfOut(amd::OclElf* v) { elfOut_ = v; }
|
||||
amd::Elf* elfOut() { return elfOut_; }
|
||||
void elfOut(amd::Elf* v) { elfOut_ = v; }
|
||||
|
||||
//! Create and save ELF binary image
|
||||
bool createElfBinary(bool doencrypt, Program::type_t type);
|
||||
@@ -908,7 +908,7 @@ class ClBinary : public amd::HeapObject {
|
||||
//! Loads llvmir binary from OCL binary file
|
||||
bool loadLlvmBinary(
|
||||
std::string& llvmBinary, //!< LLVMIR binary code
|
||||
amd::OclElf::oclElfSections& elfSectionType //!< LLVMIR binary is in SPIR format
|
||||
amd::Elf::ElfSections& elfSectionType //!< LLVMIR binary is in SPIR format
|
||||
) const;
|
||||
|
||||
//! Loads compile options from OCL binary file
|
||||
@@ -928,7 +928,7 @@ class ClBinary : public amd::HeapObject {
|
||||
);
|
||||
|
||||
//! Check if the binary is recompilable
|
||||
bool isRecompilable(std::string& llvmBinary, amd::OclElf::oclElfPlatform thePlatform);
|
||||
bool isRecompilable(std::string& llvmBinary, amd::Elf::ElfPlatform thePlatform);
|
||||
|
||||
void saveOrigBinary(const char* origBinary, size_t origSize) {
|
||||
origBinary_ = origBinary;
|
||||
@@ -1024,8 +1024,8 @@ class ClBinary : public amd::HeapObject {
|
||||
int encryptCode_; //!< Encryption Code for input binary (0 for not encrypted)
|
||||
|
||||
protected:
|
||||
amd::OclElf* elfIn_; //!< ELF object for input ELF binary
|
||||
amd::OclElf* elfOut_; //!< ELF object for output ELF binary
|
||||
amd::Elf* elfIn_; //!< ELF object for input ELF binary
|
||||
amd::Elf* elfOut_; //!< ELF object for output ELF binary
|
||||
BinaryImageFormat format_; //!< which binary image format to use
|
||||
};
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ Program::Program(amd::Device& device, amd::Program& owner)
|
||||
flags_(0),
|
||||
clBinary_(nullptr),
|
||||
llvmBinary_(),
|
||||
elfSectionType_(amd::OclElf::LLVMIR),
|
||||
elfSectionType_(amd::Elf::LLVMIR),
|
||||
compileOptions_(),
|
||||
linkOptions_(),
|
||||
binaryElf_(nullptr),
|
||||
@@ -579,7 +579,7 @@ bool Program::compileImplLC(const std::string& sourceCode,
|
||||
const char* xLang = options->oVariables->XLang;
|
||||
if (xLang != nullptr) {
|
||||
if (strcmp(xLang,"asm") == 0) {
|
||||
clBinary()->elfOut()->addSection(amd::OclElf::SOURCE, sourceCode.data(), sourceCode.size());
|
||||
clBinary()->elfOut()->addSection(amd::Elf::SOURCE, sourceCode.data(), sourceCode.size());
|
||||
return true;
|
||||
} else if (!strcmp(xLang,"cl")) {
|
||||
buildLog_ += "Unsupported language: \"" + std::string(xLang) + "\".\n";
|
||||
@@ -684,14 +684,13 @@ bool Program::compileImplLC(const std::string& sourceCode,
|
||||
// Destroy the original LLVM binary, received after compilation
|
||||
delete[] binaryData;
|
||||
|
||||
elfSectionType_ = amd::OclElf::LLVMIR;
|
||||
elfSectionType_ = amd::Elf::LLVMIR;
|
||||
|
||||
if (clBinary()->saveSOURCE()) {
|
||||
clBinary()->elfOut()->addSection(amd::OclElf::SOURCE, sourceCode.data(), sourceCode.size());
|
||||
clBinary()->elfOut()->addSection(amd::Elf::SOURCE, sourceCode.data(), sourceCode.size());
|
||||
}
|
||||
if (clBinary()->saveLLVMIR()) {
|
||||
clBinary()->elfOut()->addSection(amd::OclElf::LLVMIR, llvmBinary_.data(), llvmBinary_.size(),
|
||||
false);
|
||||
clBinary()->elfOut()->addSection(amd::Elf::LLVMIR, llvmBinary_.data(), llvmBinary_.size());
|
||||
// store the original compile options
|
||||
clBinary()->storeCompileOptions(compileOptions_);
|
||||
}
|
||||
@@ -857,7 +856,7 @@ bool Program::linkImplLC(const std::vector<Program*>& inputPrograms,
|
||||
}
|
||||
|
||||
if (result) {
|
||||
result = (program->elfSectionType_ == amd::OclElf::LLVMIR);
|
||||
result = (program->elfSectionType_ == amd::Elf::LLVMIR);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
@@ -908,11 +907,10 @@ bool Program::linkImplLC(const std::vector<Program*>& inputPrograms,
|
||||
// Destroy llvm binary, received after compilation
|
||||
delete[] binaryData;
|
||||
|
||||
elfSectionType_ = amd::OclElf::LLVMIR;
|
||||
elfSectionType_ = amd::Elf::LLVMIR;
|
||||
|
||||
if (clBinary()->saveLLVMIR()) {
|
||||
clBinary()->elfOut()->addSection(amd::OclElf::LLVMIR, llvmBinary_.data(), llvmBinary_.size(),
|
||||
false);
|
||||
clBinary()->elfOut()->addSection(amd::Elf::LLVMIR, llvmBinary_.data(), llvmBinary_.size());
|
||||
// store the original link options
|
||||
clBinary()->storeLinkOptions(linkOptions_);
|
||||
// store the original compile options
|
||||
@@ -1075,7 +1073,7 @@ bool Program::linkImplLC(amd::option::Options* options) {
|
||||
case ACL_TYPE_ASM_TEXT: {
|
||||
char* section;
|
||||
size_t sz;
|
||||
clBinary()->elfOut()->getSection(amd::OclElf::SOURCE, §ion, &sz);
|
||||
clBinary()->elfOut()->getSection(amd::Elf::SOURCE, §ion, &sz);
|
||||
|
||||
if (addCodeObjData(section, sz, AMD_COMGR_DATA_KIND_BC, "Assembly Text",
|
||||
&inputs) != AMD_COMGR_STATUS_SUCCESS) {
|
||||
@@ -2382,33 +2380,32 @@ bool Program::FindGlobalVarSize(void* binary, size_t binSize) {
|
||||
size_t dynamicSize = 0;
|
||||
size_t progvarsWriteSize = 0;
|
||||
|
||||
// Begin the Elf image from memory
|
||||
Elf* e = elf_memory((char*)binary, binSize, nullptr);
|
||||
if (elf_kind(e) != ELF_K_ELF) {
|
||||
buildLog_ += "Error while reading the ELF program binary\n";
|
||||
amd::Elf elfIn(ELFCLASSNONE, reinterpret_cast<const char *>(binary), binSize,
|
||||
nullptr, amd::Elf::ELF_C_READ);
|
||||
|
||||
if (!elfIn.isSuccessful()) {
|
||||
buildLog_ += "Creating input amd::Elf object failed\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t numpHdrs;
|
||||
if (elf_getphdrnum(e, &numpHdrs) != 0) {
|
||||
buildLog_ += "Error while reading the ELF program binary\n";
|
||||
return false;
|
||||
}
|
||||
auto numpHdrs = elfIn.getSegmentNum();
|
||||
bool metadata_found = false;
|
||||
for (size_t i = 0; i < numpHdrs; ++i) {
|
||||
GElf_Phdr pHdr;
|
||||
if (gelf_getphdr(e, i, &pHdr) != &pHdr) {
|
||||
for (unsigned int i = 0; i < numpHdrs; ++i) {
|
||||
amd::ELFIO::segment* seg = nullptr;
|
||||
if (!elfIn.getSegment(i, seg)) {
|
||||
continue;
|
||||
}
|
||||
// Look for the runtime metadata note
|
||||
if (pHdr.p_type == PT_NOTE && pHdr.p_align >= sizeof(int)) {
|
||||
if (seg->get_type() == PT_NOTE && seg->get_align() >= sizeof(int)) {
|
||||
// Iterate over the notes in this segment
|
||||
address ptr = (address)binary + pHdr.p_offset;
|
||||
address segmentEnd = ptr + pHdr.p_filesz;
|
||||
address ptr = (address)binary + seg->get_offset();
|
||||
address segmentEnd = ptr + seg->get_file_size();
|
||||
|
||||
while (ptr < segmentEnd) {
|
||||
Elf_Note* note = (Elf_Note*)ptr;
|
||||
address name = (address)¬e[1];
|
||||
// see spec of note:
|
||||
// https://docs.oracle.com/cd/E19683-01/816-1386/6m7qcoblj/index.html#chapter6-18048
|
||||
auto note = reinterpret_cast<amd::Elf::ElfNote*>(ptr);
|
||||
address name = reinterpret_cast<address>(¬e[1]);
|
||||
address desc = name + amd::alignUp(note->n_namesz, sizeof(int));
|
||||
|
||||
if (note->n_type == 7 ||
|
||||
@@ -2447,21 +2444,19 @@ bool Program::FindGlobalVarSize(void* binary, size_t binSize) {
|
||||
}
|
||||
}
|
||||
// Accumulate the size of R & !X loadable segments
|
||||
else if (pHdr.p_type == PT_LOAD && !(pHdr.p_flags & PF_X)) {
|
||||
if (pHdr.p_flags & PF_R) {
|
||||
progvarsTotalSize += pHdr.p_memsz;
|
||||
else if (seg->get_type() == PT_LOAD && !(seg->get_flags() & PF_X)) {
|
||||
if (seg->get_flags() & PF_R) {
|
||||
progvarsTotalSize += seg->get_memory_size();
|
||||
}
|
||||
if (pHdr.p_flags & PF_W) {
|
||||
progvarsWriteSize += pHdr.p_memsz;
|
||||
if (seg->get_flags() & PF_W) {
|
||||
progvarsWriteSize += seg->get_memory_size();
|
||||
}
|
||||
}
|
||||
else if (pHdr.p_type == PT_DYNAMIC) {
|
||||
dynamicSize += pHdr.p_memsz;
|
||||
else if (seg->get_type() == PT_DYNAMIC) {
|
||||
dynamicSize += seg->get_memory_size();
|
||||
}
|
||||
}
|
||||
|
||||
elf_end(e);
|
||||
|
||||
if (!metadata_found) {
|
||||
buildLog_ += "Error: runtime metadata section not present in ELF program binary\n";
|
||||
return false;
|
||||
|
||||
@@ -103,7 +103,7 @@ class Program : public amd::HeapObject {
|
||||
|
||||
ClBinary* clBinary_; //!< The CL program binary file
|
||||
std::string llvmBinary_; //!< LLVM IR binary code
|
||||
amd::OclElf::oclElfSections elfSectionType_; //!< LLVM IR binary code is in SPIR format
|
||||
amd::Elf::ElfSections elfSectionType_; //!< LLVM IR binary code is in SPIR format
|
||||
std::string compileOptions_; //!< compile/build options.
|
||||
std::string linkOptions_; //!< link options.
|
||||
//!< the option arg passed in to clCompileProgram(), clLinkProgram(),
|
||||
@@ -324,7 +324,7 @@ class Program : public amd::HeapObject {
|
||||
//! Finds the total size of all global variables in the program
|
||||
bool FindGlobalVarSize(void* binary, size_t binSize);
|
||||
|
||||
bool isElf(const char* bin) const { return amd::isElfMagic(bin); }
|
||||
bool isElf(const char* bin) const { return amd::Elf::isElfMagic(bin); }
|
||||
|
||||
virtual bool defineGlobalVar(const char* name, void* dptr) {
|
||||
ShouldNotReachHere();
|
||||
|
||||
@@ -38,7 +38,7 @@ typedef struct {
|
||||
SymInfo[NDX_HEADER] : SymbolInfo for kernel header
|
||||
SymInfo[NDX_AMDIL] : SymbolInfo for kernel's amdil
|
||||
*/
|
||||
amd::OclElf::SymbolInfo SymInfo[NDX_LAST];
|
||||
amd::Elf::SymbolInfo SymInfo[NDX_LAST];
|
||||
} ElfSymbol_t;
|
||||
}
|
||||
|
||||
@@ -58,12 +58,12 @@ bool ClBinary::loadKernels(NullProgram& program, bool* hasRecompiled) {
|
||||
// Target should be 15 bit maximum. Should check this somewhere.
|
||||
uint32_t target = static_cast<uint32_t>(dev().calTarget());
|
||||
uint16_t elf_target;
|
||||
amd::OclElf::oclElfPlatform platform;
|
||||
amd::Elf::ElfPlatform platform;
|
||||
if (!elfIn()->getTarget(elf_target, platform)) {
|
||||
LogError("The OCL binary image loading failed: incorrect format");
|
||||
return false;
|
||||
}
|
||||
if (platform == amd::OclElf::COMPLIB_PLATFORM) {
|
||||
if (platform == amd::Elf::COMPLIB_PLATFORM) {
|
||||
// BIF 3.0
|
||||
uint32_t flag;
|
||||
aclTargetInfo tgtInfo = aclGetTargetInfo("amdil", dev().hwInfo()->targetName_, NULL);
|
||||
@@ -76,7 +76,7 @@ bool ClBinary::loadKernels(NullProgram& program, bool* hasRecompiled) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (((platform != amd::OclElf::CAL_PLATFORM) || ((uint32_t)target != elf_target))) {
|
||||
if (((platform != amd::Elf::CAL_PLATFORM) || ((uint32_t)target != elf_target))) {
|
||||
LogError("The OCL binary image loading failed: different target");
|
||||
return false;
|
||||
}
|
||||
@@ -109,10 +109,10 @@ bool ClBinary::loadKernels(NullProgram& program, bool* hasRecompiled) {
|
||||
*/
|
||||
bool usedebugil = program.getCompilerOptions()->oVariables->UseDebugIL;
|
||||
|
||||
for (amd::Sym_Handle sym = elfIn()->nextSymbol(NULL); sym != NULL;
|
||||
sym = elfIn()->nextSymbol(sym)) {
|
||||
amd::OclElf::SymbolInfo symInfo;
|
||||
if (!elfIn()->getSymbolInfo(sym, &symInfo)) {
|
||||
int num = elfIn()->getSymbolNum();
|
||||
for (int index = 0; index < num; index++) {
|
||||
amd::Elf::SymbolInfo symInfo;
|
||||
if (!elfIn()->getSymbolInfo(index, &symInfo)) {
|
||||
LogError("LoadKernelFromElf: getSymbolInfo() fails");
|
||||
return false;
|
||||
}
|
||||
@@ -131,7 +131,7 @@ bool ClBinary::loadKernels(NullProgram& program, bool* hasRecompiled) {
|
||||
FName.append("_kernel"); // make the kernel's linkage name
|
||||
|
||||
ElfSymbol_t* elfsymbol = tempObj.functionNameMap[FName];
|
||||
amd::OclElf::SymbolInfo* sinfo = (elfsymbol != NULL) ? &(elfsymbol->SymInfo[0]) : NULL;
|
||||
amd::Elf::SymbolInfo* sinfo = (elfsymbol != NULL) ? &(elfsymbol->SymInfo[0]) : NULL;
|
||||
|
||||
// Add info for this elf symbol into tempobj's functionNameMap[]
|
||||
int index = -1;
|
||||
@@ -168,7 +168,6 @@ bool ClBinary::loadKernels(NullProgram& program, bool* hasRecompiled) {
|
||||
if (elfsymbol == NULL) {
|
||||
elfsymbol = new ElfSymbol_t();
|
||||
sinfo = &(elfsymbol->SymInfo[0]);
|
||||
::memset(sinfo, 0, NDX_LAST * sizeof(amd::OclElf::SymbolInfo));
|
||||
tempObj.functionNameMap[FName] = elfsymbol;
|
||||
|
||||
elfsymbol->IsKernel = isKernel;
|
||||
@@ -182,7 +181,7 @@ bool ClBinary::loadKernels(NullProgram& program, bool* hasRecompiled) {
|
||||
char* section;
|
||||
size_t sz;
|
||||
|
||||
if (elfIn_->getSection(amd::OclElf::ILDEBUG, §ion, &sz)) {
|
||||
if (elfIn_->getSection(amd::Elf::ILDEBUG, §ion, &sz)) {
|
||||
// Get debugIL
|
||||
programil.append(section, sz);
|
||||
} else {
|
||||
@@ -221,10 +220,9 @@ bool ClBinary::loadKernels(NullProgram& program, bool* hasRecompiled) {
|
||||
ElfSymbol_t* elfsymbol = tempObj.functionNameMap[kn];
|
||||
if (elfsymbol == NULL) {
|
||||
elfsymbol = new ElfSymbol_t();
|
||||
::memset(elfsymbol->SymInfo, 0, NDX_LAST * sizeof(amd::OclElf::SymbolInfo));
|
||||
tempObj.functionNameMap[kn] = elfsymbol;
|
||||
}
|
||||
amd::OclElf::SymbolInfo* sinfo = &(elfsymbol->SymInfo[0]);
|
||||
amd::Elf::SymbolInfo* sinfo = &(elfsymbol->SymInfo[0]);
|
||||
|
||||
elfsymbol->IsKernel = true;
|
||||
sinfo[NDX_AMDIL].address = const_cast<char*>(ilstr.data());
|
||||
@@ -248,7 +246,7 @@ bool ClBinary::loadKernels(NullProgram& program, bool* hasRecompiled) {
|
||||
fmetadata.append(it.first);
|
||||
fmetadata.append("_fmetadata");
|
||||
|
||||
if (!elfOut()->addSymbol(amd::OclElf::RODATA, fmetadata.c_str(),
|
||||
if (!elfOut()->addSymbol(amd::Elf::RODATA, fmetadata.c_str(),
|
||||
elfsymbol->SymInfo[NDX_METADATA].address,
|
||||
elfsymbol->SymInfo[NDX_METADATA].size)) {
|
||||
LogError("AddSymbol() failed to add fmetadata");
|
||||
@@ -257,7 +255,7 @@ bool ClBinary::loadKernels(NullProgram& program, bool* hasRecompiled) {
|
||||
}
|
||||
continue;
|
||||
}
|
||||
amd::OclElf::SymbolInfo* sinfo = &(elfsymbol->SymInfo[0]);
|
||||
amd::Elf::SymbolInfo* sinfo = &(elfsymbol->SymInfo[0]);
|
||||
std::string FName = it.first;
|
||||
|
||||
// For this kernel, get the demangled kernel name, which is used to identify each kernel.
|
||||
@@ -297,7 +295,7 @@ bool ClBinary::loadKernels(NullProgram& program, bool* hasRecompiled) {
|
||||
}
|
||||
|
||||
assert((func->metadata_.end_ == 0) && "ILFunc init failed");
|
||||
amd::OclElf::SymbolInfo* si = &(sym->SymInfo[0]);
|
||||
amd::Elf::SymbolInfo* si = &(sym->SymInfo[0]);
|
||||
if (si[NDX_METADATA].size > 0) {
|
||||
std::string meta(si[NDX_METADATA].address, si[NDX_METADATA].size);
|
||||
if (!program.parseFuncMetadata(meta, 0, std::string::npos)) {
|
||||
@@ -383,7 +381,7 @@ bool ClBinary::storeKernel(const std::string& name, const NullKernel* nullKernel
|
||||
if (saveAMDIL() && (ilSource.size() > 0)) {
|
||||
// Save IL (this is the per-kernel IL)
|
||||
std::string ilName = "__OpenCL_" + name + "_amdil";
|
||||
if (!elfOut()->addSymbol(amd::OclElf::ILTEXT, ilName.c_str(), ilSource.data(),
|
||||
if (!elfOut()->addSymbol(amd::Elf::ILTEXT, ilName.c_str(), ilSource.data(),
|
||||
ilSource.size())) {
|
||||
LogError("AddElfSymbol failed");
|
||||
return false;
|
||||
@@ -391,7 +389,7 @@ bool ClBinary::storeKernel(const std::string& name, const NullKernel* nullKernel
|
||||
|
||||
std::string metaName = "__OpenCL_" + name + "_metadata";
|
||||
// Save metadata symbols in .rodata
|
||||
if (!elfOut()->addSymbol(amd::OclElf::RODATA, metaName.c_str(), metadata.data(),
|
||||
if (!elfOut()->addSymbol(amd::Elf::RODATA, metaName.c_str(), metadata.data(),
|
||||
metadata.size())) {
|
||||
LogError("AddElfSymbol failed");
|
||||
return false;
|
||||
@@ -408,7 +406,7 @@ bool ClBinary::storeKernel(const std::string& name, const NullKernel* nullKernel
|
||||
if (!kernelMetaStored) {
|
||||
std::string metaName = "__OpenCL_" + name + "_metadata";
|
||||
// Save metadata symbols in .rodata
|
||||
if (!elfOut()->addSymbol(amd::OclElf::RODATA, metaName.c_str(), metadata.data(),
|
||||
if (!elfOut()->addSymbol(amd::Elf::RODATA, metaName.c_str(), metadata.data(),
|
||||
metadata.size())) {
|
||||
LogError("AddSymbol failed");
|
||||
return false;
|
||||
@@ -422,7 +420,7 @@ bool ClBinary::storeKernel(const std::string& name, const NullKernel* nullKernel
|
||||
delete[] isacode;
|
||||
return false;
|
||||
}
|
||||
if (!elfOut()->addSymbol(amd::OclElf::CAL, kernelName.c_str(), isacode, binarySize)) {
|
||||
if (!elfOut()->addSymbol(amd::Elf::CAL, kernelName.c_str(), isacode, binarySize)) {
|
||||
LogError("AddElfSymbol failed");
|
||||
return false;
|
||||
}
|
||||
@@ -446,7 +444,7 @@ bool ClBinary::storeKernel(const std::string& name, const NullKernel* nullKernel
|
||||
// VERSION_1
|
||||
kHeader.version_ = VERSION_CURRENT;
|
||||
|
||||
if (!elfOut()->addSymbol(amd::OclElf::RODATA, headerName.c_str(), &kHeader, sizeof(kHeader))) {
|
||||
if (!elfOut()->addSymbol(amd::Elf::RODATA, headerName.c_str(), &kHeader, sizeof(kHeader))) {
|
||||
LogError("AddElfSymbol failed");
|
||||
return false;
|
||||
}
|
||||
@@ -458,10 +456,10 @@ bool ClBinary::loadGlobalData(Program& program) {
|
||||
const char __OpenCL_[] = "__OpenCL_";
|
||||
const char _global[] = "_global";
|
||||
|
||||
for (amd::Sym_Handle sym = elfIn()->nextSymbol(NULL); sym != NULL;
|
||||
sym = elfIn()->nextSymbol(sym)) {
|
||||
amd::OclElf::SymbolInfo symInfo;
|
||||
if (!elfIn()->getSymbolInfo(sym, &symInfo)) {
|
||||
int num = elfIn()->getSymbolNum();
|
||||
for (int index = 0; index < num; index++) {
|
||||
amd::Elf::SymbolInfo symInfo;
|
||||
if (!elfIn()->getSymbolInfo(index, &symInfo)) {
|
||||
LogError("LoadGlobalDataFromElf: getSymbolInfo() fails");
|
||||
return false;
|
||||
}
|
||||
@@ -495,7 +493,7 @@ bool ClBinary::storeGlobalData(const void* globalData, size_t dataSize, uint ind
|
||||
std::stringstream glbName;
|
||||
glbName << "__OpenCL_" << index << "_global";
|
||||
|
||||
if (!elfOut()->addSymbol(amd::OclElf::RODATA, glbName.str().c_str(), globalData, dataSize)) {
|
||||
if (!elfOut()->addSymbol(amd::Elf::RODATA, glbName.str().c_str(), globalData, dataSize)) {
|
||||
LogError("addSymbol() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ class ClBinary : public device::ClBinary {
|
||||
uint32_t target = static_cast<uint32_t>(dev().calTarget());
|
||||
assert(((0xFFFF8000 & target) == 0) && "ASIC target ID >= 2^15");
|
||||
uint16_t elf_target = (uint16_t)(0x7FFF & target);
|
||||
return elfOut()->setTarget(elf_target, amd::OclElf::CAL_PLATFORM);
|
||||
return elfOut()->setTarget(elf_target, amd::Elf::CAL_PLATFORM);
|
||||
}
|
||||
|
||||
//! Clear elf out.
|
||||
|
||||
@@ -226,7 +226,7 @@ bool NullProgram::compileImpl(const std::string& src,
|
||||
}
|
||||
|
||||
llvmBinary_.assign(reinterpret_cast<const char*>(ir), len);
|
||||
elfSectionType_ = amd::OclElf::LLVMIR;
|
||||
elfSectionType_ = amd::Elf::LLVMIR;
|
||||
aclBinaryFini(bin);
|
||||
|
||||
for (size_t i = 0; i < headerFileNames.size(); ++i) {
|
||||
@@ -241,10 +241,10 @@ bool NullProgram::compileImpl(const std::string& src,
|
||||
#endif
|
||||
|
||||
if (clBinary()->saveSOURCE()) {
|
||||
clBinary()->elfOut()->addSection(amd::OclElf::SOURCE, sourceCode.data(), sourceCode.size());
|
||||
clBinary()->elfOut()->addSection(amd::Elf::SOURCE, sourceCode.data(), sourceCode.size());
|
||||
}
|
||||
if (clBinary()->saveLLVMIR()) {
|
||||
clBinary()->elfOut()->addSection(amd::OclElf::LLVMIR, llvmBinary_.data(), llvmBinary_.size(),
|
||||
clBinary()->elfOut()->addSection(amd::Elf::LLVMIR, llvmBinary_.data(), llvmBinary_.size(),
|
||||
false);
|
||||
// store the original compile options
|
||||
clBinary()->storeCompileOptions(compileOptions_);
|
||||
@@ -272,11 +272,11 @@ int NullProgram::compileBinaryToIL(amd::option::Options* options) {
|
||||
aclSections_0_8 spirFlag;
|
||||
_acl_type_enum_0_8 aclTypeBinaryUsed;
|
||||
if (std::string::npos != options->clcOptions.find("--spirv") ||
|
||||
elfSectionType_ == amd::OclElf::SPIRV) {
|
||||
elfSectionType_ == amd::Elf::SPIRV) {
|
||||
spirFlag = aclSPIRV;
|
||||
aclTypeBinaryUsed = ACL_TYPE_SPIRV_BINARY;
|
||||
} else if (std::string::npos != options->clcOptions.find("--spir") ||
|
||||
elfSectionType_ == amd::OclElf::SPIR) {
|
||||
elfSectionType_ == amd::Elf::SPIR) {
|
||||
spirFlag = aclSPIR;
|
||||
aclTypeBinaryUsed = ACL_TYPE_SPIR_BINARY;
|
||||
} else {
|
||||
|
||||
@@ -169,8 +169,8 @@ bool NullProgram::linkImpl(amd::option::Options* options) {
|
||||
char* section;
|
||||
size_t sz;
|
||||
if (clBinary()->saveSOURCE() &&
|
||||
clBinary()->elfIn()->getSection(amd::OclElf::SOURCE, §ion, &sz)) {
|
||||
clBinary()->elfOut()->addSection(amd::OclElf::SOURCE, section, sz);
|
||||
clBinary()->elfIn()->getSection(amd::Elf::SOURCE, §ion, &sz)) {
|
||||
clBinary()->elfOut()->addSection(amd::Elf::SOURCE, section, sz);
|
||||
}
|
||||
if (clBinary()->saveLLVMIR()) {
|
||||
if (clBinary()->loadLlvmBinary(llvmBinary_, elfSectionType_) &&
|
||||
@@ -193,7 +193,7 @@ bool NullProgram::linkImpl(amd::option::Options* options) {
|
||||
}
|
||||
return true;
|
||||
} else if (clBinary()->loadLlvmBinary(llvmBinary_, elfSectionType_) &&
|
||||
clBinary()->isRecompilable(llvmBinary_, amd::OclElf::CAL_PLATFORM)) {
|
||||
clBinary()->isRecompilable(llvmBinary_, amd::Elf::CAL_PLATFORM)) {
|
||||
char* section;
|
||||
size_t sz;
|
||||
|
||||
@@ -205,8 +205,8 @@ bool NullProgram::linkImpl(amd::option::Options* options) {
|
||||
}
|
||||
|
||||
if (clBinary()->saveSOURCE() &&
|
||||
clBinary()->elfIn()->getSection(amd::OclElf::SOURCE, §ion, &sz)) {
|
||||
clBinary()->elfOut()->addSection(amd::OclElf::SOURCE, section, sz);
|
||||
clBinary()->elfIn()->getSection(amd::Elf::SOURCE, §ion, &sz)) {
|
||||
clBinary()->elfOut()->addSection(amd::Elf::SOURCE, section, sz);
|
||||
}
|
||||
if (clBinary()->saveLLVMIR()) {
|
||||
clBinary()->elfOut()->addSection(elfSectionType_, llvmBinary_.data(), llvmBinary_.size(),
|
||||
@@ -239,7 +239,7 @@ bool NullProgram::linkImpl(amd::option::Options* options) {
|
||||
size_t dbgSize = debugILStr.size();
|
||||
// Add an IL section that contains debug information and is the
|
||||
// output of LLVM codegen.
|
||||
clBinary()->elfOut()->addSection(amd::OclElf::ILDEBUG, dbgSec, dbgSize);
|
||||
clBinary()->elfOut()->addSection(amd::Elf::ILDEBUG, dbgSec, dbgSize);
|
||||
|
||||
if ((dbgSize > 0) && options->isDumpFlagSet(amd::option::DUMP_DEBUGIL)) {
|
||||
std::string debugilWithLine;
|
||||
@@ -275,7 +275,7 @@ bool NullProgram::linkImpl(amd::option::Options* options) {
|
||||
continue;
|
||||
}
|
||||
clBinary()->elfOut()->addSection(
|
||||
static_cast<amd::OclElf::oclElfSections>(x + amd::OclElf::DEBUG_INFO), dbgSec, dbgSize);
|
||||
static_cast<amd::Elf::ElfSections>(x + amd::Elf::DEBUG_INFO), dbgSec, dbgSize);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -410,7 +410,7 @@ bool NullProgram::linkImpl(amd::option::Options* options) {
|
||||
aStream << "__OpenCL_" << baseFunc->name_ << "_fmetadata";
|
||||
std::string metaName = aStream.str();
|
||||
// Save metadata symbols in .rodata
|
||||
if (!clBinary()->elfOut()->addSymbol(amd::OclElf::RODATA, metaName.c_str(),
|
||||
if (!clBinary()->elfOut()->addSymbol(amd::Elf::RODATA, metaName.c_str(),
|
||||
metadataStr.data(), metadataStr.size())) {
|
||||
buildLog_ += "Internal error: addSymbol failed!\n";
|
||||
LogError("AddSymbol failed");
|
||||
@@ -437,7 +437,7 @@ bool NullProgram::linkImpl(amd::option::Options* options) {
|
||||
bool NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
|
||||
amd::option::Options* options, bool createLibrary) {
|
||||
std::vector<std::string*> llvmBinaries(inputPrograms.size());
|
||||
std::vector<amd::OclElf::oclElfSections> elfSectionType(inputPrograms.size());
|
||||
std::vector<amd::Elf::ElfSections> elfSectionType(inputPrograms.size());
|
||||
auto it = inputPrograms.cbegin();
|
||||
const auto itEnd = inputPrograms.cend();
|
||||
for (size_t i = 0; it != itEnd; ++it, ++i) {
|
||||
@@ -464,7 +464,7 @@ bool NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!program->clBinary()->isRecompilable(program->llvmBinary_, amd::OclElf::CAL_PLATFORM)) {
|
||||
if (!program->clBinary()->isRecompilable(program->llvmBinary_, amd::Elf::CAL_PLATFORM)) {
|
||||
buildLog_ +=
|
||||
"Internal error: Input OpenCL binary is not"
|
||||
" for the target!\n";
|
||||
@@ -477,8 +477,8 @@ bool NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
|
||||
size_t sz;
|
||||
|
||||
if (clBinary()->saveSOURCE() &&
|
||||
clBinary()->elfIn()->getSection(amd::OclElf::SOURCE, §ion, &sz)) {
|
||||
clBinary()->elfOut()->addSection(amd::OclElf::SOURCE, section, sz);
|
||||
clBinary()->elfIn()->getSection(amd::Elf::SOURCE, §ion, &sz)) {
|
||||
clBinary()->elfOut()->addSection(amd::Elf::SOURCE, section, sz);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -505,9 +505,9 @@ bool NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
|
||||
}
|
||||
|
||||
_bif_sections_enum_0_8 aclTypeUsed;
|
||||
if (elfSectionType[i] == amd::OclElf::SPIRV) {
|
||||
if (elfSectionType[i] == amd::Elf::SPIRV) {
|
||||
aclTypeUsed = aclSPIRV;
|
||||
} else if (elfSectionType[i] == amd::OclElf::SPIR) {
|
||||
} else if (elfSectionType[i] == amd::Elf::SPIR) {
|
||||
aclTypeUsed = aclSPIR;
|
||||
} else {
|
||||
aclTypeUsed = aclLLVMIR;
|
||||
@@ -542,9 +542,9 @@ bool NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
|
||||
|
||||
size_t size = 0;
|
||||
_bif_sections_enum_0_8 aclTypeUsed;
|
||||
if (elfSectionType[0] == amd::OclElf::SPIRV && numLibs == 0) {
|
||||
if (elfSectionType[0] == amd::Elf::SPIRV && numLibs == 0) {
|
||||
aclTypeUsed = aclSPIRV;
|
||||
} else if (elfSectionType[0] == amd::OclElf::SPIR && numLibs == 0) {
|
||||
} else if (elfSectionType[0] == amd::Elf::SPIR && numLibs == 0) {
|
||||
aclTypeUsed = aclSPIR;
|
||||
} else {
|
||||
aclTypeUsed = aclLLVMIR;
|
||||
@@ -556,7 +556,7 @@ bool NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
|
||||
}
|
||||
|
||||
llvmBinary_.assign(reinterpret_cast<const char*>(llvmir), size);
|
||||
elfSectionType_ = amd::OclElf::LLVMIR;
|
||||
elfSectionType_ = amd::Elf::LLVMIR;
|
||||
} while (0);
|
||||
|
||||
std::for_each(libs.begin(), libs.end(), std::ptr_fun(aclBinaryFini));
|
||||
@@ -567,7 +567,7 @@ bool NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
|
||||
}
|
||||
|
||||
if (clBinary()->saveLLVMIR()) {
|
||||
clBinary()->elfOut()->addSection(amd::OclElf::LLVMIR, llvmBinary_.data(), llvmBinary_.size(),
|
||||
clBinary()->elfOut()->addSection(amd::Elf::LLVMIR, llvmBinary_.data(), llvmBinary_.size(),
|
||||
false);
|
||||
// store the original link options
|
||||
clBinary()->storeLinkOptions(linkOptions_);
|
||||
@@ -603,7 +603,7 @@ bool NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
|
||||
size_t dbgSize = debugILStr.size();
|
||||
// Add an IL section that contains debug information and is the
|
||||
// output of LLVM codegen.
|
||||
clBinary()->elfOut()->addSection(amd::OclElf::ILDEBUG, dbgSec, dbgSize);
|
||||
clBinary()->elfOut()->addSection(amd::Elf::ILDEBUG, dbgSec, dbgSize);
|
||||
|
||||
if ((dbgSize > 0) && options->isDumpFlagSet(amd::option::DUMP_DEBUGIL)) {
|
||||
std::string debugilWithLine;
|
||||
@@ -639,7 +639,7 @@ bool NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
|
||||
continue;
|
||||
}
|
||||
clBinary()->elfOut()->addSection(
|
||||
static_cast<amd::OclElf::oclElfSections>(x + amd::OclElf::DEBUG_INFO), dbgSec, dbgSize);
|
||||
static_cast<amd::Elf::ElfSections>(x + amd::Elf::DEBUG_INFO), dbgSec, dbgSize);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -774,7 +774,7 @@ bool NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
|
||||
aStream << "__OpenCL_" << baseFunc->name_ << "_fmetadata";
|
||||
std::string metaName = aStream.str();
|
||||
// Save metadata symbols in .rodata
|
||||
if (!clBinary()->elfOut()->addSymbol(amd::OclElf::RODATA, metaName.c_str(),
|
||||
if (!clBinary()->elfOut()->addSymbol(amd::Elf::RODATA, metaName.c_str(),
|
||||
metadataStr.data(), metadataStr.size())) {
|
||||
buildLog_ += "Internal error: addSymbol failed!\n";
|
||||
LogError("AddSymbol failed");
|
||||
|
||||
@@ -109,8 +109,6 @@ target_include_directories(rocclrpal
|
||||
${PROJECT_SOURCE_DIR}/compiler/lib
|
||||
${PROJECT_SOURCE_DIR}/compiler/lib/include
|
||||
${PROJECT_SOURCE_DIR}/compiler/lib/backends/common
|
||||
${PROJECT_SOURCE_DIR}/compiler/lib/loaders/elf/utils/common
|
||||
${PROJECT_SOURCE_DIR}/compiler/lib/loaders/elf/utils/libelf
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${ROCM_OCL_INCLUDES}
|
||||
${ROCR_INCLUDES})
|
||||
|
||||
@@ -32,9 +32,6 @@
|
||||
#include "hsa.h"
|
||||
#include "hsa_ext_image.h"
|
||||
#include "amd_hsa_loader.hpp"
|
||||
#if defined(USE_COMGR_LIBRARY)
|
||||
#include "gelf.h"
|
||||
#endif // defined(USE_COMGR_LIBRARY)
|
||||
|
||||
namespace pal {
|
||||
|
||||
|
||||
@@ -28,8 +28,7 @@ target_include_directories(oclrocm
|
||||
${PROJECT_SOURCE_DIR}/compiler/lib
|
||||
${PROJECT_SOURCE_DIR}/compiler/lib/include
|
||||
${PROJECT_SOURCE_DIR}/compiler/lib/backends/common
|
||||
${PROJECT_SOURCE_DIR}/compiler/lib/loaders/elf/utils/common
|
||||
${PROJECT_SOURCE_DIR}/compiler/lib/loaders/elf/utils/libelf
|
||||
${PROJECT_SOURCE_DIR}/elf
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${ROCM_OCL_INCLUDES}
|
||||
$<TARGET_PROPERTY:hsa-runtime64::hsa-runtime64,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||
|
||||
@@ -24,9 +24,6 @@
|
||||
|
||||
#include "utils/options.hpp"
|
||||
#include "rockernel.hpp"
|
||||
#if defined(USE_COMGR_LIBRARY)
|
||||
#include <gelf.h>
|
||||
#endif // defined(USE_COMGR_LIBRARY)
|
||||
|
||||
#include "utils/bif_section_labels.hpp"
|
||||
#include "amd_hsa_kernel_code.h"
|
||||
@@ -112,7 +109,7 @@ bool Program::initClBinary(char* binaryIn, size_t size) {
|
||||
}
|
||||
|
||||
// Both 32-bit and 64-bit are allowed!
|
||||
if (!amd::isElfMagic(bin)) {
|
||||
if (!amd::Elf::isElfMagic(bin)) {
|
||||
// Invalid binary.
|
||||
if (decryptedBin != nullptr) {
|
||||
delete[] decryptedBin;
|
||||
|
||||
+666
-1161
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
+178
-176
@@ -24,13 +24,14 @@
|
||||
#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"
|
||||
#include "elfio/elfio.hpp"
|
||||
#include <sstream>
|
||||
using amd::ELFIO::Elf64_Ehdr;
|
||||
using amd::ELFIO::Elf64_Shdr;
|
||||
|
||||
// Not sure where to put these in the libelf
|
||||
#define AMD_BIF2 2 // AMD BIF Version 2.0
|
||||
@@ -48,6 +49,9 @@
|
||||
#ifndef EM_AMDIL
|
||||
#define EM_AMDIL 0x4154
|
||||
#endif
|
||||
#ifndef EM_AMDIL_64
|
||||
#define EM_AMDIL_64 0x4155
|
||||
#endif
|
||||
#ifndef EM_ATI_CALIMAGE_BINARY
|
||||
#define EM_ATI_CALIMAGE_BINARY 125
|
||||
#endif
|
||||
@@ -66,19 +70,11 @@
|
||||
#ifndef ELFOSABI_CALIMAGE
|
||||
#define ELFOSABI_CALIMAGE 100
|
||||
#endif
|
||||
|
||||
namespace amd {
|
||||
using namespace amd::ELFIO;
|
||||
|
||||
// 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
|
||||
class Elf
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
@@ -86,7 +82,7 @@ public:
|
||||
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;
|
||||
} ElfBase;
|
||||
|
||||
typedef enum {
|
||||
// NOTE!!! Never remove an entry or change the order.
|
||||
@@ -102,7 +98,7 @@ public:
|
||||
CPU_LAST = CPU_FEATURES_LAST + CPU_BASE,
|
||||
|
||||
OCL_TARGETS_LAST,
|
||||
} oclElfTargets;
|
||||
} ElfTargets;
|
||||
|
||||
typedef enum {
|
||||
CAL_PLATFORM = 0,
|
||||
@@ -110,7 +106,7 @@ public:
|
||||
COMPLIB_PLATFORM = 2,
|
||||
LC_PLATFORM = 3,
|
||||
LAST_PLATFORM = 4
|
||||
} oclElfPlatform;
|
||||
} ElfPlatform;
|
||||
|
||||
typedef enum {
|
||||
LLVMIR = 0,
|
||||
@@ -144,71 +140,93 @@ public:
|
||||
SPIR,
|
||||
SPIRV,
|
||||
RUNTIME_METADATA,
|
||||
OCL_ELF_SECTIONS_LAST
|
||||
} oclElfSections;
|
||||
ELF_SECTIONS_LAST
|
||||
} ElfSections;
|
||||
|
||||
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;
|
||||
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
|
||||
} ElfCmd;
|
||||
|
||||
struct SymbolInfo {
|
||||
std::string sec_name; //! section name
|
||||
const char* sec_addr; //! section address
|
||||
uint64_t sec_size; //! section size
|
||||
std::string sym_name; //! symbol name
|
||||
const char* address; //! address of corresponding to symbol data
|
||||
uint64_t size; //! size of data corresponding to symbol
|
||||
SymbolInfo():
|
||||
sec_name(), sec_addr(nullptr), sec_size(0), sym_name(), address(nullptr), size(0) { }
|
||||
|
||||
SymbolInfo(const char* sename, const char* seaddr, uint64_t sesize, const char* syname,
|
||||
const char* syaddr, uint64_t sysize): sec_name(sename), sec_addr(seaddr),
|
||||
sec_size(sesize), sym_name(syname), address(syaddr), size(sysize) { }
|
||||
};
|
||||
|
||||
/*
|
||||
* Note descriptors.
|
||||
* Follow https://docs.oracle.com/cd/E19683-01/816-1386/6m7qcoblj/index.html#chapter6-18048
|
||||
*/
|
||||
struct ElfNote {
|
||||
uint32_t n_namesz; /* Length of note's name. */
|
||||
uint32_t n_descsz; /* Length of note's value. */
|
||||
uint32_t n_type; /* Type of note. */
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
// file descriptor
|
||||
int _fd;
|
||||
// elfio object for reading and writting
|
||||
elfio _elfio;
|
||||
|
||||
// file name
|
||||
const char* _fname;
|
||||
|
||||
// pointer to libelf structure
|
||||
::Elf* _e;
|
||||
|
||||
// Error Object
|
||||
mutable OclElfErr _err;
|
||||
std::string _fname;
|
||||
|
||||
// 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 !
|
||||
// The memory is owned by the client, not this Elf object !
|
||||
const char* _rawElfBytes;
|
||||
uint64_t _rawElfSize;
|
||||
|
||||
// Read, write, or read and write for this Elf object
|
||||
const Elf_Cmd _elfCmd;
|
||||
const ElfCmd _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;
|
||||
Elf64_Word _shstrtab_ndx; // Indexes of .shstrtab. Must be valid.
|
||||
Elf64_Word _strtab_ndx; // Indexes of .strtab. Must be valid.
|
||||
Elf64_Word _symtab_ndx; // Indexes of .symtab. May be SHN_UNDEF.
|
||||
|
||||
bool _successful;
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
OclElf object can be created for reading or writing (it could be created for
|
||||
Elf 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)
|
||||
1) Elf(eclass, rawElfBytes, rawElfSize, 0, ELF_C_READ)
|
||||
|
||||
To load ELF from raw bytes in memory and generate OclElf object. And this
|
||||
To load ELF from raw bytes in memory and generate Elf object. And this
|
||||
object is for reading only.
|
||||
|
||||
2) OclElf(eclass, NULL, 0, elfFileName|NULL, ELF_C_WRITE)
|
||||
2) Elf(eclass, nullptr, 0, elfFileName|nullptr, 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'.
|
||||
is nullptr, the Elf will create a stream in memory.
|
||||
|
||||
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.
|
||||
Since we need to read the ELF into memory, the runtime can use dumpImage() to get ELF
|
||||
raw bytes by reading this file/stream.
|
||||
|
||||
'eclass' is ELF's bitness and it must be the same as the eclass of ELF to
|
||||
be loaded (for example, rawElfBytes).
|
||||
@@ -218,209 +236,193 @@ public:
|
||||
true : on success;
|
||||
false : on error.
|
||||
*/
|
||||
OclElf (
|
||||
Elf (
|
||||
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
|
||||
ElfCmd elfcmd // ELF_C_READ/ELF_C_WRITE
|
||||
);
|
||||
|
||||
~OclElf ();
|
||||
~Elf ();
|
||||
|
||||
/*
|
||||
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.
|
||||
* dumpImage() will finalize the ELF and write it into the file/stream. It then reads
|
||||
* it into the memory; and returns it via <buff, len>.
|
||||
* The memory pointed by buff is new'ed in Elf and should be deleted by caller
|
||||
* if dumpImage() succeeds.
|
||||
*/
|
||||
bool dumpImage(char** buff, size_t* len);
|
||||
bool dumpImage(std::istream& is, 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().
|
||||
* If the session doesn't exist, create a new ELF section with data <d_buf, d_size>;
|
||||
* otherwise, append the data.
|
||||
*/
|
||||
bool addSection (
|
||||
oclElfSections id,
|
||||
const void* d_buf,
|
||||
size_t d_size,
|
||||
bool do_copy = true
|
||||
ElfSections id,
|
||||
const void* d_buf,
|
||||
size_t d_size
|
||||
);
|
||||
|
||||
/*
|
||||
getSection() will return the whole section in <dst, sz>.
|
||||
|
||||
The memory pointed by <dst, sz> is owned by the OclElf object.
|
||||
* Return the whole section in <dst, sz>.
|
||||
* The memory pointed by <dst, sz> is owned by the Elf object.
|
||||
*/
|
||||
bool getSection(oclElfSections id, char** dst, size_t* sz) const;
|
||||
|
||||
bool getSection(ElfSections 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().
|
||||
* Add a symbol with name 'symbolName' and data <buffer, size>
|
||||
* into the ELF. 'id' indicates which section <buffer, size> will go
|
||||
* into.
|
||||
*/
|
||||
bool addSymbol(
|
||||
oclElfSections id, // Section in which symbol is added
|
||||
ElfSections 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
|
||||
);
|
||||
size_t size // Symbol's size
|
||||
);
|
||||
|
||||
/*
|
||||
* getSymbol() will return the data associated with
|
||||
* the symbol from the Elf.
|
||||
*
|
||||
* The memory pointed by <buffer, size> is owned by the OclElf object
|
||||
* Return the data associated with the symbol from the Elf.
|
||||
* The memory pointed by <buffer, size> is owned by the Elf object
|
||||
*/
|
||||
bool getSymbol(
|
||||
oclElfSections id, // Section in which symbol is in
|
||||
ElfSections 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;
|
||||
|
||||
/* Return number of symbols in SYMTAB section */
|
||||
unsigned int getSymbolNum() const;
|
||||
|
||||
/* Return SymbolInfo of the index-th symbol in SYMTAB section */
|
||||
bool getSymbolInfo(unsigned int index, SymbolInfo* symInfo) 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.
|
||||
* Adds a note with name 'noteName' and description "noteDesc"
|
||||
* into the .note section of ELF. Length of note description is "descSize'.
|
||||
*/
|
||||
bool getSymbolInfo(Sym_Handle sym, SymbolInfo* symInfo) const;
|
||||
Sym_Handle nextSymbol(Sym_Handle symhandle) const;
|
||||
bool addNote(const char* noteName, const char* noteDesc, size_t descSize);
|
||||
|
||||
/*
|
||||
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'.
|
||||
*/
|
||||
* Return the description of a note whose name is 'noteName'
|
||||
* in 'noteDesc'.
|
||||
* Return the length of the description in 'descSize'.
|
||||
* The memory pointed by <noteDesc, descSize> is owned by the Elf object.
|
||||
*/
|
||||
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 machine and platform (target) for which elf is built */
|
||||
bool getTarget(uint16_t& machine, ElfPlatform& platform) const;
|
||||
bool setTarget(uint16_t machine, ElfPlatform platform);
|
||||
|
||||
/*
|
||||
Get/set elf type field from header
|
||||
*/
|
||||
/* Get/set elf type field from header */
|
||||
bool getType(uint16_t &type);
|
||||
bool setType(uint16_t type);
|
||||
|
||||
/*
|
||||
Get/set elf flag field from header.
|
||||
*/
|
||||
/* 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.
|
||||
* Clear() will return the status of Elf to just after ctor() is invoked.
|
||||
* 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); }
|
||||
bool isSuccessful() { return _successful; }
|
||||
|
||||
bool isHsaCo() const { return _elfio.get_machine() == EM_AMDGPU; }
|
||||
|
||||
/* Return number of segments */
|
||||
unsigned int getSegmentNum() const;
|
||||
|
||||
/* Return segment at index */
|
||||
bool getSegment(const unsigned int index, segment*& seg);
|
||||
|
||||
/* Return size of elf file */
|
||||
static uint64_t getElfSize(const void *emi);
|
||||
|
||||
/* is it ELF */
|
||||
static bool isElfMagic(const char* p);
|
||||
|
||||
// is it ELF for CAL ?
|
||||
static bool isCALTarget(const char* p, signed char ec);
|
||||
private:
|
||||
|
||||
/* Initialization */
|
||||
bool Init();
|
||||
|
||||
/*
|
||||
Initialize ELF object by creating ELF header and key sections such as
|
||||
.shstrtab, .strtab, and .symtab.
|
||||
* 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
|
||||
/* Setup a section header */
|
||||
bool setupShdr (
|
||||
ElfSections id,
|
||||
section* section,
|
||||
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().
|
||||
* Create a new data into an existing section.
|
||||
* And the section is returned in 'sec'.
|
||||
*/
|
||||
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
|
||||
bool createElfData(
|
||||
section*& sec,
|
||||
ElfSections id,
|
||||
const char* d_buf,
|
||||
size_t d_size
|
||||
);
|
||||
|
||||
/*
|
||||
Add a new data into a section by creating a new data descriptor.
|
||||
And the new data's offset is returned in 'outOffset'.
|
||||
* Assumes that .shstrtab and .strtab have been created already.
|
||||
* Create a new section (id) with data <d_buf, d_size>.
|
||||
* Return the valid section* on success; nullptr on error.
|
||||
*/
|
||||
section* newSection (
|
||||
ElfSections id,
|
||||
const char* d_buf,
|
||||
size_t d_size
|
||||
);
|
||||
|
||||
/*
|
||||
* Add a new data into the existing section.
|
||||
* And the new data's offset is returned in 'outOffset'.
|
||||
*/
|
||||
bool addSectionData(
|
||||
Elf64_Xword& outOffset,
|
||||
oclElfSections id,
|
||||
Elf_Xword& outOffset,
|
||||
ElfSections id,
|
||||
const void* buffer,
|
||||
size_t size,
|
||||
bool do_copy=true // if true, add a copy of buffer
|
||||
size_t size
|
||||
);
|
||||
|
||||
// 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;
|
||||
|
||||
//
|
||||
/*
|
||||
* Return an index to the .shstrtab in 'outNdx' for "name" if it
|
||||
* is in .shstrtab (outNdx == 0 means it is not in .shstrtab).
|
||||
*/
|
||||
bool getShstrtabNdx(Elf64_Word& outNdx, const char*);
|
||||
|
||||
void* oclelf_allocAndCopy(void* p, size_t sz);
|
||||
void* oclelf_calloc(size_t sz);
|
||||
/*
|
||||
* Generate UUID string
|
||||
*/
|
||||
static std::string generateUUIDV4();
|
||||
|
||||
/*
|
||||
* Return newly-allocated memory or nullptr
|
||||
* The allocated memory is guaranteed to be initialized to zero.
|
||||
*/
|
||||
void* xmalloc(const size_t len);
|
||||
|
||||
void* allocAndCopy(void* p, size_t sz);
|
||||
void* calloc(size_t sz);
|
||||
|
||||
void elfMemoryRelease();
|
||||
};
|
||||
|
||||
@@ -1,300 +0,0 @@
|
||||
/* Copyright (c) 2010-present Advanced Micro Devices, Inc.
|
||||
|
||||
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. */
|
||||
|
||||
#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
|
||||
@@ -1,162 +0,0 @@
|
||||
/* Copyright (c) 2008-present Advanced Micro Devices, Inc.
|
||||
|
||||
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. */
|
||||
|
||||
#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,855 @@
|
||||
/*
|
||||
Copyright (C) 2001-2015 by Serge Lamikhov-Center
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef ELFTYPES_H
|
||||
#define ELFTYPES_H
|
||||
|
||||
#ifndef ELFIO_NO_OWN_TYPES
|
||||
#if !defined(ELFIO_NO_CSTDINT) && !defined(ELFIO_NO_INTTYPES)
|
||||
#include <stdint.h>
|
||||
#else
|
||||
typedef unsigned char uint8_t;
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef signed short int16_t;
|
||||
#ifdef _MSC_VER
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef signed __int64 int64_t;
|
||||
#else
|
||||
typedef unsigned int uint32_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef signed long long int64_t;
|
||||
#endif // _MSC_VER
|
||||
#endif // ELFIO_NO_CSTDINT
|
||||
#endif // ELFIO_NO_OWN_TYPES
|
||||
|
||||
namespace amd {
|
||||
namespace ELFIO {
|
||||
|
||||
// Attention! Platform depended definitions.
|
||||
typedef uint16_t Elf_Half;
|
||||
typedef uint32_t Elf_Word;
|
||||
typedef int32_t Elf_Sword;
|
||||
typedef uint64_t Elf_Xword;
|
||||
typedef int64_t Elf_Sxword;
|
||||
|
||||
typedef uint32_t Elf32_Addr;
|
||||
typedef uint32_t Elf32_Off;
|
||||
typedef uint64_t Elf64_Addr;
|
||||
typedef uint64_t Elf64_Off;
|
||||
|
||||
#define Elf32_Half Elf_Half
|
||||
#define Elf64_Half Elf_Half
|
||||
#define Elf32_Word Elf_Word
|
||||
#define Elf64_Word Elf_Word
|
||||
#define Elf32_Sword Elf_Sword
|
||||
#define Elf64_Sword Elf_Sword
|
||||
#define Elf64_Xword Elf_Xword
|
||||
#define Elf64_Sxword Elf_Sxword
|
||||
|
||||
///////////////////////
|
||||
// ELF Header Constants
|
||||
|
||||
// File type
|
||||
#define ET_NONE 0
|
||||
#define ET_REL 1
|
||||
#define ET_EXEC 2
|
||||
#define ET_DYN 3
|
||||
#define ET_CORE 4
|
||||
#define ET_LOOS 0xFE00
|
||||
#define ET_HIOS 0xFEFF
|
||||
#define ET_LOPROC 0xFF00
|
||||
#define ET_HIPROC 0xFFFF
|
||||
|
||||
|
||||
#define EM_NONE 0 // No machine
|
||||
#define EM_M32 1 // AT&T WE 32100
|
||||
#define EM_SPARC 2 // SUN SPARC
|
||||
#define EM_386 3 // Intel 80386
|
||||
#define EM_68K 4 // Motorola m68k family
|
||||
#define EM_88K 5 // Motorola m88k family
|
||||
#define EM_486 6 // Intel 80486// Reserved for future use
|
||||
#define EM_860 7 // Intel 80860
|
||||
#define EM_MIPS 8 // MIPS R3000 (officially, big-endian only)
|
||||
#define EM_S370 9 // IBM System/370
|
||||
#define EM_MIPS_RS3_LE 10 // MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated
|
||||
#define EM_res011 11 // Reserved
|
||||
#define EM_res012 12 // Reserved
|
||||
#define EM_res013 13 // Reserved
|
||||
#define EM_res014 14 // Reserved
|
||||
#define EM_PARISC 15 // HPPA
|
||||
#define EM_res016 16 // Reserved
|
||||
#define EM_VPP550 17 // Fujitsu VPP500
|
||||
#define EM_SPARC32PLUS 18 // Sun's "v8plus"
|
||||
#define EM_960 19 // Intel 80960
|
||||
#define EM_PPC 20 // PowerPC
|
||||
#define EM_PPC64 21 // 64-bit PowerPC
|
||||
#define EM_S390 22 // IBM S/390
|
||||
#define EM_SPU 23 // Sony/Toshiba/IBM SPU
|
||||
#define EM_res024 24 // Reserved
|
||||
#define EM_res025 25 // Reserved
|
||||
#define EM_res026 26 // Reserved
|
||||
#define EM_res027 27 // Reserved
|
||||
#define EM_res028 28 // Reserved
|
||||
#define EM_res029 29 // Reserved
|
||||
#define EM_res030 30 // Reserved
|
||||
#define EM_res031 31 // Reserved
|
||||
#define EM_res032 32 // Reserved
|
||||
#define EM_res033 33 // Reserved
|
||||
#define EM_res034 34 // Reserved
|
||||
#define EM_res035 35 // Reserved
|
||||
#define EM_V800 36 // NEC V800 series
|
||||
#define EM_FR20 37 // Fujitsu FR20
|
||||
#define EM_RH32 38 // TRW RH32
|
||||
#define EM_MCORE 39 // Motorola M*Core // May also be taken by Fujitsu MMA
|
||||
#define EM_RCE 39 // Old name for MCore
|
||||
#define EM_ARM 40 // ARM
|
||||
#define EM_OLD_ALPHA 41 // Digital Alpha
|
||||
#define EM_SH 42 // Renesas (formerly Hitachi) / SuperH SH
|
||||
#define EM_SPARCV9 43 // SPARC v9 64-bit
|
||||
#define EM_TRICORE 44 // Siemens Tricore embedded processor
|
||||
#define EM_ARC 45 // ARC Cores
|
||||
#define EM_H8_300 46 // Renesas (formerly Hitachi) H8/300
|
||||
#define EM_H8_300H 47 // Renesas (formerly Hitachi) H8/300H
|
||||
#define EM_H8S 48 // Renesas (formerly Hitachi) H8S
|
||||
#define EM_H8_500 49 // Renesas (formerly 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 Multimedia Accelerator
|
||||
#define EM_PCP 55 // Siemens PCP
|
||||
#define EM_NCPU 56 // Sony nCPU embedded RISC processor
|
||||
#define EM_NDR1 57 // Denso NDR1 microprocesspr
|
||||
#define EM_STARCORE 58 // Motorola Star*Core processor
|
||||
#define EM_ME16 59 // Toyota ME16 processor
|
||||
#define EM_ST100 60 // STMicroelectronics ST100 processor
|
||||
#define EM_TINYJ 61 // Advanced Logic Corp. TinyJ embedded processor
|
||||
#define EM_X86_64 62 // Advanced Micro Devices X86-64 processor
|
||||
#define EM_PDSP 63 // Sony DSP Processor
|
||||
#define EM_PDP10 64 // Digital Equipment Corp. PDP-10
|
||||
#define EM_PDP11 65 // Digital Equipment Corp. PDP-11
|
||||
#define EM_FX66 66 // Siemens FX66 microcontroller
|
||||
#define EM_ST9PLUS 67 // STMicroelectronics ST9+ 8/16 bit microcontroller
|
||||
#define EM_ST7 68 // STMicroelectronics ST7 8-bit microcontroller
|
||||
#define EM_68HC16 69 // Motorola MC68HC16 Microcontroller
|
||||
#define EM_68HC11 70 // Motorola MC68HC11 Microcontroller
|
||||
#define EM_68HC08 71 // Motorola MC68HC08 Microcontroller
|
||||
#define EM_68HC05 72 // Motorola MC68HC05 Microcontroller
|
||||
#define EM_SVX 73 // Silicon Graphics SVx
|
||||
#define EM_ST19 74 // STMicroelectronics ST19 8-bit cpu
|
||||
#define EM_VAX 75 // Digital VAX
|
||||
#define EM_CRIS 76 // Axis Communications 32-bit embedded processor
|
||||
#define EM_JAVELIN 77 // Infineon Technologies 32-bit embedded cpu
|
||||
#define EM_FIREPATH 78 // Element 14 64-bit DSP processor
|
||||
#define EM_ZSP 79 // LSI Logic's 16-bit DSP processor
|
||||
#define EM_MMIX 80 // Donald Knuth's educational 64-bit processor
|
||||
#define EM_HUANY 81 // Harvard's machine-independent format
|
||||
#define EM_PRISM 82 // SiTera Prism
|
||||
#define EM_AVR 83 // Atmel AVR 8-bit microcontroller
|
||||
#define EM_FR30 84 // Fujitsu FR30
|
||||
#define EM_D10V 85 // Mitsubishi D10V
|
||||
#define EM_D30V 86 // Mitsubishi D30V
|
||||
#define EM_V850 87 // NEC v850
|
||||
#define EM_M32R 88 // Renesas M32R (formerly Mitsubishi M32R)
|
||||
#define EM_MN10300 89 // Matsushita MN10300
|
||||
#define EM_MN10200 90 // Matsushita MN10200
|
||||
#define EM_PJ 91 // picoJava
|
||||
#define EM_OPENRISC 92 // OpenRISC 32-bit embedded processor
|
||||
#define EM_ARC_A5 93 // ARC Cores Tangent-A5
|
||||
#define EM_XTENSA 94 // Tensilica Xtensa Architecture
|
||||
#define EM_VIDEOCORE 95 // Alphamosaic VideoCore processor
|
||||
#define EM_TMM_GPP 96 // Thompson Multimedia General Purpose Processor
|
||||
#define EM_NS32K 97 // National Semiconductor 32000 series
|
||||
#define EM_TPC 98 // Tenor Network TPC processor
|
||||
#define EM_SNP1K 99 // Trebia SNP 1000 processor
|
||||
#define EM_ST200 100 // STMicroelectronics ST200 microcontroller
|
||||
#define EM_IP2K 101 // Ubicom IP2022 micro controller
|
||||
#define EM_MAX 102 // MAX Processor
|
||||
#define EM_CR 103 // National Semiconductor CompactRISC
|
||||
#define EM_F2MC16 104 // Fujitsu F2MC16
|
||||
#define EM_MSP430 105 // TI msp430 micro controller
|
||||
#define EM_BLACKFIN 106 // ADI Blackfin
|
||||
#define EM_SE_C33 107 // S1C33 Family of Seiko Epson processors
|
||||
#define EM_SEP 108 // Sharp embedded microprocessor
|
||||
#define EM_ARCA 109 // Arca RISC Microprocessor
|
||||
#define EM_UNICORE 110 // Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University
|
||||
#define EM_EXCESS 111 // eXcess: 16/32/64-bit configurable embedded CPU
|
||||
#define EM_DXP 112 // Icera Semiconductor Inc. Deep Execution Processor
|
||||
#define EM_ALTERA_NIOS2 113 // Altera Nios II soft-core processor
|
||||
#define EM_CRX 114 // National Semiconductor CRX
|
||||
#define EM_XGATE 115 // Motorola XGATE embedded processor
|
||||
#define EM_C166 116 // Infineon C16x/XC16x processor
|
||||
#define EM_M16C 117 // Renesas M16C series microprocessors
|
||||
#define EM_DSPIC30F 118 // Microchip Technology dsPIC30F Digital Signal Controller
|
||||
#define EM_CE 119 // Freescale Communication Engine RISC core
|
||||
#define EM_M32C 120 // Renesas M32C series microprocessors
|
||||
#define EM_res121 121 // Reserved
|
||||
#define EM_res122 122 // Reserved
|
||||
#define EM_res123 123 // Reserved
|
||||
#define EM_res124 124 // Reserved
|
||||
#define EM_res125 125 // Reserved
|
||||
#define EM_res126 126 // Reserved
|
||||
#define EM_res127 127 // Reserved
|
||||
#define EM_res128 128 // Reserved
|
||||
#define EM_res129 129 // Reserved
|
||||
#define EM_res130 130 // Reserved
|
||||
#define EM_TSK3000 131 // Altium TSK3000 core
|
||||
#define EM_RS08 132 // Freescale RS08 embedded processor
|
||||
#define EM_res133 133 // Reserved
|
||||
#define EM_ECOG2 134 // Cyan Technology eCOG2 microprocessor
|
||||
#define EM_SCORE 135 // Sunplus Score
|
||||
#define EM_SCORE7 135 // Sunplus S+core7 RISC processor
|
||||
#define EM_DSP24 136 // New Japan Radio (NJR) 24-bit DSP Processor
|
||||
#define EM_VIDEOCORE3 137 // Broadcom VideoCore III processor
|
||||
#define EM_LATTICEMICO32 138 // RISC processor for Lattice FPGA architecture
|
||||
#define EM_SE_C17 139 // Seiko Epson C17 family
|
||||
#define EM_TI_C6000 140 // Texas Instruments TMS320C6000 DSP family
|
||||
#define EM_TI_C2000 141 // Texas Instruments TMS320C2000 DSP family
|
||||
#define EM_TI_C5500 142 // Texas Instruments TMS320C55x DSP family
|
||||
#define EM_res143 143 // Reserved
|
||||
#define EM_res144 144 // Reserved
|
||||
#define EM_res145 145 // Reserved
|
||||
#define EM_res146 146 // Reserved
|
||||
#define EM_res147 147 // Reserved
|
||||
#define EM_res148 148 // Reserved
|
||||
#define EM_res149 149 // Reserved
|
||||
#define EM_res150 150 // Reserved
|
||||
#define EM_res151 151 // Reserved
|
||||
#define EM_res152 152 // Reserved
|
||||
#define EM_res153 153 // Reserved
|
||||
#define EM_res154 154 // Reserved
|
||||
#define EM_res155 155 // Reserved
|
||||
#define EM_res156 156 // Reserved
|
||||
#define EM_res157 157 // Reserved
|
||||
#define EM_res158 158 // Reserved
|
||||
#define EM_res159 159 // Reserved
|
||||
#define EM_MMDSP_PLUS 160 // STMicroelectronics 64bit VLIW Data Signal Processor
|
||||
#define EM_CYPRESS_M8C 161 // Cypress M8C microprocessor
|
||||
#define EM_R32C 162 // Renesas R32C series microprocessors
|
||||
#define EM_TRIMEDIA 163 // NXP Semiconductors TriMedia architecture family
|
||||
#define EM_QDSP6 164 // QUALCOMM DSP6 Processor
|
||||
#define EM_8051 165 // Intel 8051 and variants
|
||||
#define EM_STXP7X 166 // STMicroelectronics STxP7x family
|
||||
#define EM_NDS32 167 // Andes Technology compact code size embedded RISC processor family
|
||||
#define EM_ECOG1 168 // Cyan Technology eCOG1X family
|
||||
#define EM_ECOG1X 168 // Cyan Technology eCOG1X family
|
||||
#define EM_MAXQ30 169 // Dallas Semiconductor MAXQ30 Core Micro-controllers
|
||||
#define EM_XIMO16 170 // New Japan Radio (NJR) 16-bit DSP Processor
|
||||
#define EM_MANIK 171 // M2000 Reconfigurable RISC Microprocessor
|
||||
#define EM_CRAYNV2 172 // Cray Inc. NV2 vector architecture
|
||||
#define EM_RX 173 // Renesas RX family
|
||||
#define EM_METAG 174 // Imagination Technologies META processor architecture
|
||||
#define EM_MCST_ELBRUS 175 // MCST Elbrus general purpose hardware architecture
|
||||
#define EM_ECOG16 176 // Cyan Technology eCOG16 family
|
||||
#define EM_CR16 177 // National Semiconductor CompactRISC 16-bit processor
|
||||
#define EM_ETPU 178 // Freescale Extended Time Processing Unit
|
||||
#define EM_SLE9X 179 // Infineon Technologies SLE9X core
|
||||
#define EM_L1OM 180 // Intel L1OM
|
||||
#define EM_INTEL181 181 // Reserved by Intel
|
||||
#define EM_INTEL182 182 // Reserved by Intel
|
||||
#define EM_res183 183 // Reserved by ARM
|
||||
#define EM_res184 184 // Reserved by ARM
|
||||
#define EM_AVR32 185 // Atmel Corporation 32-bit microprocessor family
|
||||
#define EM_STM8 186 // STMicroeletronics STM8 8-bit microcontroller
|
||||
#define EM_TILE64 187 // Tilera TILE64 multicore architecture family
|
||||
#define EM_TILEPRO 188 // Tilera TILEPro multicore architecture family
|
||||
#define EM_MICROBLAZE 189 // Xilinx MicroBlaze 32-bit RISC soft processor core
|
||||
#define EM_CUDA 190 // NVIDIA CUDA architecture
|
||||
#define EM_TILEGX 191 // Tilera TILE-Gx multicore architecture family
|
||||
#define EM_CLOUDSHIELD 192 // CloudShield architecture family
|
||||
#define EM_COREA_1ST 193 // KIPO-KAIST Core-A 1st generation processor family
|
||||
#define EM_COREA_2ND 194 // KIPO-KAIST Core-A 2nd generation processor family
|
||||
#define EM_ARC_COMPACT2 195 // Synopsys ARCompact V2
|
||||
#define EM_OPEN8 196 // Open8 8-bit RISC soft processor core
|
||||
#define EM_RL78 197 // Renesas RL78 family
|
||||
#define EM_VIDEOCORE5 198 // Broadcom VideoCore V processor
|
||||
#define EM_78KOR 199 // Renesas 78KOR family
|
||||
#define EM_56800EX 200 // Freescale 56800EX Digital Signal Controller (DSC)
|
||||
#define EM_BA1 201 // Beyond BA1 CPU architecture
|
||||
#define EM_BA2 202 // Beyond BA2 CPU architecture
|
||||
#define EM_XCORE 203 // XMOS xCORE processor family
|
||||
#define EM_MCHP_PIC 204 // Microchip 8-bit PIC(r) family
|
||||
#define EM_INTEL205 205 // Reserved by Intel
|
||||
#define EM_INTEL206 206 // Reserved by Intel
|
||||
#define EM_INTEL207 207 // Reserved by Intel
|
||||
#define EM_INTEL208 208 // Reserved by Intel
|
||||
#define EM_INTEL209 209 // Reserved by Intel
|
||||
#define EM_KM32 210 // KM211 KM32 32-bit processor
|
||||
#define EM_KMX32 211 // KM211 KMX32 32-bit processor
|
||||
#define EM_KMX16 212 // KM211 KMX16 16-bit processor
|
||||
#define EM_KMX8 213 // KM211 KMX8 8-bit processor
|
||||
#define EM_KVARC 214 // KM211 KVARC processor
|
||||
#define EM_CDP 215 // Paneve CDP architecture family
|
||||
#define EM_COGE 216 // Cognitive Smart Memory Processor
|
||||
#define EM_COOL 217 // iCelero CoolEngine
|
||||
#define EM_NORC 218 // Nanoradio Optimized RISC
|
||||
#define EM_CSR_KALIMBA 219 // CSR Kalimba architecture family
|
||||
#define EM_Z80 220 // Zilog Z80
|
||||
#define EM_VISIUM 221 // Controls and Data Services VISIUMcore processor
|
||||
#define EM_FT32 222 // FTDI Chip FT32 high performance 32-bit RISC architecture
|
||||
#define EM_MOXIE 223 // Moxie processor family
|
||||
#define EM_AMDGPU 224 // AMD GPU architecture
|
||||
#define EM_RISCV 243 // RISC-V
|
||||
#define EM_LANAI 244 // Lanai processor
|
||||
#define EM_CEVA 245 // CEVA Processor Architecture Family
|
||||
#define EM_CEVA_X2 246 // CEVA X2 Processor Family
|
||||
#define EM_BPF 247 // Linux BPF – in-kernel virtual machine
|
||||
|
||||
// File version
|
||||
#define EV_NONE 0
|
||||
#define EV_CURRENT 1
|
||||
|
||||
// Identification index
|
||||
#define EI_MAG0 0
|
||||
#define EI_MAG1 1
|
||||
#define EI_MAG2 2
|
||||
#define EI_MAG3 3
|
||||
#define EI_CLASS 4
|
||||
#define EI_DATA 5
|
||||
#define EI_VERSION 6
|
||||
#define EI_OSABI 7
|
||||
#define EI_ABIVERSION 8
|
||||
#define EI_PAD 9
|
||||
#define EI_NIDENT 16
|
||||
|
||||
// Magic number
|
||||
#define ELFMAG0 0x7F
|
||||
#define ELFMAG1 'E'
|
||||
#define ELFMAG2 'L'
|
||||
#define ELFMAG3 'F'
|
||||
|
||||
// File class
|
||||
#define ELFCLASSNONE 0
|
||||
#define ELFCLASS32 1
|
||||
#define ELFCLASS64 2
|
||||
|
||||
// Encoding
|
||||
#define ELFDATANONE 0
|
||||
#define ELFDATA2LSB 1
|
||||
#define ELFDATA2MSB 2
|
||||
|
||||
// OS extensions
|
||||
#define ELFOSABI_NONE 0 // No extensions or unspecified
|
||||
#define ELFOSABI_HPUX 1 // Hewlett-Packard HP-UX
|
||||
#define ELFOSABI_NETBSD 2 // NetBSD
|
||||
#define ELFOSABI_LINUX 3 // Linux
|
||||
#define ELFOSABI_SOLARIS 6 // Sun Solaris
|
||||
#define ELFOSABI_AIX 7 // AIX
|
||||
#define ELFOSABI_IRIX 8 // IRIX
|
||||
#define ELFOSABI_FREEBSD 9 // FreeBSD
|
||||
#define ELFOSABI_TRU64 10 // Compaq TRU64 UNIX
|
||||
#define ELFOSABI_MODESTO 11 // Novell Modesto
|
||||
#define ELFOSABI_OPENBSD 12 // Open BSD
|
||||
#define ELFOSABI_OPENVMS 13 // Open VMS
|
||||
#define ELFOSABI_NSK 14 // Hewlett-Packard Non-Stop Kernel
|
||||
#define ELFOSABI_AROS 15 // Amiga Research OS
|
||||
#define ELFOSABI_FENIXOS 16 // The FenixOS highly scalable multi-core OS
|
||||
// 64-255 Architecture-specific value range
|
||||
#define ELFOSABI_AMDGPU_HSA 64 // AMDGPU OS for HSA compatible compute
|
||||
// kernels.
|
||||
#define ELFOSABI_AMDGPU_PAL 65 // AMDGPU OS for AMD PAL compatible graphics
|
||||
// shaders and compute kernels.
|
||||
#define ELFOSABI_AMDGPU_MESA3D 66 // AMDGPU OS for Mesa3D compatible graphics
|
||||
// shaders and compute kernels.
|
||||
|
||||
|
||||
// AMDGPU specific e_flags
|
||||
#define EF_AMDGPU_MACH 0x0ff // AMDGPU processor selection mask.
|
||||
#define EF_AMDGPU_XNACK 0x100 // Indicates if the XNACK target feature is
|
||||
// enabled for all code contained in the ELF.
|
||||
// AMDGPU processors
|
||||
#define EF_AMDGPU_MACH_NONE 0x000 // Unspecified processor.
|
||||
#define EF_AMDGPU_MACH_R600_R600 0x001
|
||||
#define EF_AMDGPU_MACH_R600_R630 0x002
|
||||
#define EF_AMDGPU_MACH_R600_RS880 0x003
|
||||
#define EF_AMDGPU_MACH_R600_RV670 0x004
|
||||
#define EF_AMDGPU_MACH_R600_RV710 0x005
|
||||
#define EF_AMDGPU_MACH_R600_RV730 0x006
|
||||
#define EF_AMDGPU_MACH_R600_RV770 0x007
|
||||
#define EF_AMDGPU_MACH_R600_CEDAR 0x008
|
||||
#define EF_AMDGPU_MACH_R600_CYPRESS 0x009
|
||||
#define EF_AMDGPU_MACH_R600_JUNIPER 0x00a
|
||||
#define EF_AMDGPU_MACH_R600_REDWOOD 0x00b
|
||||
#define EF_AMDGPU_MACH_R600_SUMO 0x00c
|
||||
#define EF_AMDGPU_MACH_R600_BARTS 0x00d
|
||||
#define EF_AMDGPU_MACH_R600_CAICOS 0x00e
|
||||
#define EF_AMDGPU_MACH_R600_CAYMAN 0x00f
|
||||
#define EF_AMDGPU_MACH_R600_TURKS 0x010
|
||||
#define EF_AMDGPU_MACH_R600_RESERVED_FIRST 0x011
|
||||
#define EF_AMDGPU_MACH_R600_RESERVED_LAST 0x01f
|
||||
#define EF_AMDGPU_MACH_R600_FIRST EF_AMDGPU_MACH_R600_R600
|
||||
#define EF_AMDGPU_MACH_R600_LAST EF_AMDGPU_MACH_R600_TURKS
|
||||
#define EF_AMDGPU_MACH_AMDGCN_GFX600 0x020
|
||||
#define EF_AMDGPU_MACH_AMDGCN_GFX601 0x021
|
||||
#define EF_AMDGPU_MACH_AMDGCN_GFX700 0x022
|
||||
#define EF_AMDGPU_MACH_AMDGCN_GFX701 0x023
|
||||
#define EF_AMDGPU_MACH_AMDGCN_GFX702 0x024
|
||||
#define EF_AMDGPU_MACH_AMDGCN_GFX703 0x025
|
||||
#define EF_AMDGPU_MACH_AMDGCN_GFX704 0x026
|
||||
#define EF_AMDGPU_MACH_AMDGCN_GFX801 0x028
|
||||
#define EF_AMDGPU_MACH_AMDGCN_GFX802 0x029
|
||||
#define EF_AMDGPU_MACH_AMDGCN_GFX803 0x02a
|
||||
#define EF_AMDGPU_MACH_AMDGCN_GFX810 0x02b
|
||||
#define EF_AMDGPU_MACH_AMDGCN_GFX900 0x02c
|
||||
#define EF_AMDGPU_MACH_AMDGCN_GFX902 0x02d
|
||||
#define EF_AMDGPU_MACH_AMDGCN_GFX904 0x02e
|
||||
#define EF_AMDGPU_MACH_AMDGCN_GFX906 0x02f
|
||||
#define EF_AMDGPU_MACH_AMDGCN_RESERVED0 0x027
|
||||
#define EF_AMDGPU_MACH_AMDGCN_RESERVED1 0x030
|
||||
#define EF_AMDGPU_MACH_AMDGCN_FIRST EF_AMDGPU_MACH_AMDGCN_GFX600
|
||||
#define EF_AMDGPU_MACH_AMDGCN_LAST EF_AMDGPU_MACH_AMDGCN_GFX906
|
||||
|
||||
/////////////////////
|
||||
// Sections constants
|
||||
|
||||
// Section indexes
|
||||
#define SHN_UNDEF 0
|
||||
#define SHN_LORESERVE 0xFF00
|
||||
#define SHN_LOPROC 0xFF00
|
||||
#define SHN_HIPROC 0xFF1F
|
||||
#define SHN_LOOS 0xFF20
|
||||
#define SHN_HIOS 0xFF3F
|
||||
#define SHN_ABS 0xFFF1
|
||||
#define SHN_COMMON 0xFFF2
|
||||
#define SHN_XINDEX 0xFFFF
|
||||
#define SHN_HIRESERVE 0xFFFF
|
||||
|
||||
// Section types
|
||||
#define SHT_NULL 0
|
||||
#define SHT_PROGBITS 1
|
||||
#define SHT_SYMTAB 2
|
||||
#define SHT_STRTAB 3
|
||||
#define SHT_RELA 4
|
||||
#define SHT_HASH 5
|
||||
#define SHT_DYNAMIC 6
|
||||
#define SHT_NOTE 7
|
||||
#define SHT_NOBITS 8
|
||||
#define SHT_REL 9
|
||||
#define SHT_SHLIB 10
|
||||
#define SHT_DYNSYM 11
|
||||
#define SHT_INIT_ARRAY 14
|
||||
#define SHT_FINI_ARRAY 15
|
||||
#define SHT_PREINIT_ARRAY 16
|
||||
#define SHT_GROUP 17
|
||||
#define SHT_SYMTAB_SHNDX 18
|
||||
#define SHT_LOOS 0x60000000
|
||||
#define SHT_HIOS 0x6fffffff
|
||||
#define SHT_LOPROC 0x70000000
|
||||
#define SHT_HIPROC 0x7FFFFFFF
|
||||
#define SHT_LOUSER 0x80000000
|
||||
#define SHT_HIUSER 0xFFFFFFFF
|
||||
|
||||
// Section attribute flags
|
||||
#define SHF_WRITE 0x1
|
||||
#define SHF_ALLOC 0x2
|
||||
#define SHF_EXECINSTR 0x4
|
||||
#define SHF_MERGE 0x10
|
||||
#define SHF_STRINGS 0x20
|
||||
#define SHF_INFO_LINK 0x40
|
||||
#define SHF_LINK_ORDER 0x80
|
||||
#define SHF_OS_NONCONFORMING 0x100
|
||||
#define SHF_GROUP 0x200
|
||||
#define SHF_TLS 0x400
|
||||
#define SHF_MASKOS 0x0ff00000
|
||||
#define SHF_MASKPROC 0xF0000000
|
||||
|
||||
// Section group flags
|
||||
#define GRP_COMDAT 0x1
|
||||
#define GRP_MASKOS 0x0ff00000
|
||||
#define GRP_MASKPROC 0xf0000000
|
||||
|
||||
// Symbol binding
|
||||
#define STB_LOCAL 0
|
||||
#define STB_GLOBAL 1
|
||||
#define STB_WEAK 2
|
||||
#define STB_LOOS 10
|
||||
#define STB_HIOS 12
|
||||
#define STB_MULTIDEF 13
|
||||
#define STB_LOPROC 13
|
||||
#define STB_HIPROC 15
|
||||
|
||||
// Note types
|
||||
#define NT_AMDGPU_METADATA 1
|
||||
#define NT_AMD_AMDGPU_HSA_METADATA 10
|
||||
#define NT_AMD_AMDGPU_ISA 11
|
||||
#define NT_AMD_AMDGPU_PAL_METADATA 12
|
||||
|
||||
// Symbol types
|
||||
#define STT_NOTYPE 0
|
||||
#define STT_OBJECT 1
|
||||
#define STT_FUNC 2
|
||||
#define STT_SECTION 3
|
||||
#define STT_FILE 4
|
||||
#define STT_COMMON 5
|
||||
#define STT_TLS 6
|
||||
#define STT_LOOS 10
|
||||
#define STT_AMDGPU_HSA_KERNEL 10
|
||||
#define STT_HIOS 12
|
||||
#define STT_LOPROC 13
|
||||
#define STT_HIPROC 15
|
||||
|
||||
// Symbol visibility
|
||||
#define STV_DEFAULT 0
|
||||
#define STV_INTERNAL 1
|
||||
#define STV_HIDDEN 2
|
||||
#define STV_PROTECTED 3
|
||||
|
||||
// Undefined name
|
||||
#define STN_UNDEF 0
|
||||
|
||||
// Relocation types
|
||||
#define R_386_NONE 0
|
||||
#define R_X86_64_NONE 0
|
||||
#define R_AMDGPU_NONE 0
|
||||
#define R_386_32 1
|
||||
#define R_X86_64_64 1
|
||||
#define R_AMDGPU_ABS32_LO 1
|
||||
#define R_386_PC32 2
|
||||
#define R_X86_64_PC32 2
|
||||
#define R_AMDGPU_ABS32_HI 2
|
||||
#define R_386_GOT32 3
|
||||
#define R_X86_64_GOT32 3
|
||||
#define R_AMDGPU_ABS64 3
|
||||
#define R_386_PLT32 4
|
||||
#define R_X86_64_PLT32 4
|
||||
#define R_AMDGPU_REL32 4
|
||||
#define R_386_COPY 5
|
||||
#define R_X86_64_COPY 5
|
||||
#define R_AMDGPU_REL64 5
|
||||
#define R_386_GLOB_DAT 6
|
||||
#define R_X86_64_GLOB_DAT 6
|
||||
#define R_AMDGPU_ABS32 6
|
||||
#define R_386_JMP_SLOT 7
|
||||
#define R_X86_64_JUMP_SLOT 7
|
||||
#define R_AMDGPU_GOTPCREL 7
|
||||
#define R_386_RELATIVE 8
|
||||
#define R_X86_64_RELATIVE 8
|
||||
#define R_AMDGPU_GOTPCREL32_LO 8
|
||||
#define R_386_GOTOFF 9
|
||||
#define R_X86_64_GOTPCREL 9
|
||||
#define R_AMDGPU_GOTPCREL32_HI 9
|
||||
#define R_386_GOTPC 10
|
||||
#define R_X86_64_32 10
|
||||
#define R_AMDGPU_REL32_LO 10
|
||||
#define R_386_32PLT 11
|
||||
#define R_X86_64_32S 11
|
||||
#define R_AMDGPU_REL32_HI 11
|
||||
#define R_X86_64_16 12
|
||||
#define R_X86_64_PC16 13
|
||||
#define R_AMDGPU_RELATIVE64 13
|
||||
#define R_386_TLS_TPOFF 14
|
||||
#define R_X86_64_8 14
|
||||
#define R_386_TLS_IE 15
|
||||
#define R_X86_64_PC8 15
|
||||
#define R_386_TLS_GOTIE 16
|
||||
#define R_X86_64_DTPMOD64 16
|
||||
#define R_386_TLS_LE 17
|
||||
#define R_X86_64_DTPOFF64 17
|
||||
#define R_386_TLS_GD 18
|
||||
#define R_X86_64_TPOFF64 18
|
||||
#define R_386_TLS_LDM 19
|
||||
#define R_X86_64_TLSGD 19
|
||||
#define R_386_16 20
|
||||
#define R_X86_64_TLSLD 20
|
||||
#define R_386_PC16 21
|
||||
#define R_X86_64_DTPOFF32 21
|
||||
#define R_386_8 22
|
||||
#define R_X86_64_GOTTPOFF 22
|
||||
#define R_386_PC8 23
|
||||
#define R_X86_64_TPOFF32 23
|
||||
#define R_386_TLS_GD_32 24
|
||||
#define R_X86_64_PC64 24
|
||||
#define R_386_TLS_GD_PUSH 25
|
||||
#define R_X86_64_GOTOFF64 25
|
||||
#define R_386_TLS_GD_CALL 26
|
||||
#define R_X86_64_GOTPC32 26
|
||||
#define R_386_TLS_GD_POP 27
|
||||
#define R_X86_64_GOT64 27
|
||||
#define R_386_TLS_LDM_32 28
|
||||
#define R_X86_64_GOTPCREL64 28
|
||||
#define R_386_TLS_LDM_PUSH 29
|
||||
#define R_X86_64_GOTPC64 29
|
||||
#define R_386_TLS_LDM_CALL 30
|
||||
#define R_X86_64_GOTPLT64 30
|
||||
#define R_386_TLS_LDM_POP 31
|
||||
#define R_X86_64_PLTOFF64 31
|
||||
#define R_386_TLS_LDO_32 32
|
||||
#define R_386_TLS_IE_32 33
|
||||
#define R_386_TLS_LE_32 34
|
||||
#define R_X86_64_GOTPC32_TLSDESC 34
|
||||
#define R_386_TLS_DTPMOD32 35
|
||||
#define R_X86_64_TLSDESC_CALL 35
|
||||
#define R_386_TLS_DTPOFF32 36
|
||||
#define R_X86_64_TLSDESC 36
|
||||
#define R_386_TLS_TPOFF32 37
|
||||
#define R_X86_64_IRELATIVE 37
|
||||
#define R_386_SIZE32 38
|
||||
#define R_386_TLS_GOTDESC 39
|
||||
#define R_386_TLS_DESC_CALL 40
|
||||
#define R_386_TLS_DESC 41
|
||||
#define R_386_IRELATIVE 42
|
||||
#define R_386_GOT32X 43
|
||||
#define R_X86_64_GNU_VTINHERIT 250
|
||||
#define R_X86_64_GNU_VTENTRY 251
|
||||
|
||||
// Segment types
|
||||
#define PT_NULL 0
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define PT_INTERP 3
|
||||
#define PT_NOTE 4
|
||||
#define PT_SHLIB 5
|
||||
#define PT_PHDR 6
|
||||
#define PT_TLS 7
|
||||
#define PT_LOOS 0x60000000
|
||||
#define PT_HIOS 0x6fffffff
|
||||
#define PT_LOPROC 0x70000000
|
||||
#define PT_HIPROC 0x7FFFFFFF
|
||||
|
||||
// Segment flags
|
||||
#define PF_X 1 // Execute
|
||||
#define PF_W 2 // Write
|
||||
#define PF_R 4 // Read
|
||||
#define PF_MASKOS 0x0ff00000 // Unspecified
|
||||
#define PF_MASKPROC 0xf0000000 // Unspecified
|
||||
|
||||
// Dynamic Array Tags
|
||||
#define DT_NULL 0
|
||||
#define DT_NEEDED 1
|
||||
#define DT_PLTRELSZ 2
|
||||
#define DT_PLTGOT 3
|
||||
#define DT_HASH 4
|
||||
#define DT_STRTAB 5
|
||||
#define DT_SYMTAB 6
|
||||
#define DT_RELA 7
|
||||
#define DT_RELASZ 8
|
||||
#define DT_RELAENT 9
|
||||
#define DT_STRSZ 10
|
||||
#define DT_SYMENT 11
|
||||
#define DT_INIT 12
|
||||
#define DT_FINI 13
|
||||
#define DT_SONAME 14
|
||||
#define DT_RPATH 15
|
||||
#define DT_SYMBOLIC 16
|
||||
#define DT_REL 17
|
||||
#define DT_RELSZ 18
|
||||
#define DT_RELENT 19
|
||||
#define DT_PLTREL 20
|
||||
#define DT_DEBUG 21
|
||||
#define DT_TEXTREL 22
|
||||
#define DT_JMPREL 23
|
||||
#define DT_BIND_NOW 24
|
||||
#define DT_INIT_ARRAY 25
|
||||
#define DT_FINI_ARRAY 26
|
||||
#define DT_INIT_ARRAYSZ 27
|
||||
#define DT_FINI_ARRAYSZ 28
|
||||
#define DT_RUNPATH 29
|
||||
#define DT_FLAGS 30
|
||||
#define DT_ENCODING 32
|
||||
#define DT_PREINIT_ARRAY 32
|
||||
#define DT_PREINIT_ARRAYSZ 33
|
||||
#define DT_MAXPOSTAGS 34
|
||||
#define DT_LOOS 0x6000000D
|
||||
#define DT_HIOS 0x6ffff000
|
||||
#define DT_LOPROC 0x70000000
|
||||
#define DT_HIPROC 0x7FFFFFFF
|
||||
|
||||
// DT_FLAGS values
|
||||
#define DF_ORIGIN 0x1
|
||||
#define DF_SYMBOLIC 0x2
|
||||
#define DF_TEXTREL 0x4
|
||||
#define DF_BIND_NOW 0x8
|
||||
#define DF_STATIC_TLS 0x10
|
||||
|
||||
|
||||
// ELF file header
|
||||
struct Elf32_Ehdr {
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
Elf_Half e_type;
|
||||
Elf_Half e_machine;
|
||||
Elf_Word e_version;
|
||||
Elf32_Addr e_entry;
|
||||
Elf32_Off e_phoff;
|
||||
Elf32_Off e_shoff;
|
||||
Elf_Word e_flags;
|
||||
Elf_Half e_ehsize;
|
||||
Elf_Half e_phentsize;
|
||||
Elf_Half e_phnum;
|
||||
Elf_Half e_shentsize;
|
||||
Elf_Half e_shnum;
|
||||
Elf_Half e_shstrndx;
|
||||
};
|
||||
|
||||
struct Elf64_Ehdr {
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
Elf_Half e_type;
|
||||
Elf_Half e_machine;
|
||||
Elf_Word e_version;
|
||||
Elf64_Addr e_entry;
|
||||
Elf64_Off e_phoff;
|
||||
Elf64_Off e_shoff;
|
||||
Elf_Word e_flags;
|
||||
Elf_Half e_ehsize;
|
||||
Elf_Half e_phentsize;
|
||||
Elf_Half e_phnum;
|
||||
Elf_Half e_shentsize;
|
||||
Elf_Half e_shnum;
|
||||
Elf_Half e_shstrndx;
|
||||
};
|
||||
|
||||
|
||||
// Section header
|
||||
struct Elf32_Shdr {
|
||||
Elf_Word sh_name;
|
||||
Elf_Word sh_type;
|
||||
Elf_Word sh_flags;
|
||||
Elf32_Addr sh_addr;
|
||||
Elf32_Off sh_offset;
|
||||
Elf_Word sh_size;
|
||||
Elf_Word sh_link;
|
||||
Elf_Word sh_info;
|
||||
Elf_Word sh_addralign;
|
||||
Elf_Word sh_entsize;
|
||||
};
|
||||
|
||||
struct Elf64_Shdr {
|
||||
Elf_Word sh_name;
|
||||
Elf_Word sh_type;
|
||||
Elf_Xword sh_flags;
|
||||
Elf64_Addr sh_addr;
|
||||
Elf64_Off sh_offset;
|
||||
Elf_Xword sh_size;
|
||||
Elf_Word sh_link;
|
||||
Elf_Word sh_info;
|
||||
Elf_Xword sh_addralign;
|
||||
Elf_Xword sh_entsize;
|
||||
};
|
||||
|
||||
|
||||
// Segment header
|
||||
struct Elf32_Phdr {
|
||||
Elf_Word p_type;
|
||||
Elf32_Off p_offset;
|
||||
Elf32_Addr p_vaddr;
|
||||
Elf32_Addr p_paddr;
|
||||
Elf_Word p_filesz;
|
||||
Elf_Word p_memsz;
|
||||
Elf_Word p_flags;
|
||||
Elf_Word p_align;
|
||||
};
|
||||
|
||||
struct Elf64_Phdr {
|
||||
Elf_Word p_type;
|
||||
Elf_Word p_flags;
|
||||
Elf64_Off p_offset;
|
||||
Elf64_Addr p_vaddr;
|
||||
Elf64_Addr p_paddr;
|
||||
Elf_Xword p_filesz;
|
||||
Elf_Xword p_memsz;
|
||||
Elf_Xword p_align;
|
||||
};
|
||||
|
||||
|
||||
// Symbol table entry
|
||||
struct Elf32_Sym {
|
||||
Elf_Word st_name;
|
||||
Elf32_Addr st_value;
|
||||
Elf_Word st_size;
|
||||
unsigned char st_info;
|
||||
unsigned char st_other;
|
||||
Elf_Half st_shndx;
|
||||
};
|
||||
|
||||
struct Elf64_Sym {
|
||||
Elf_Word st_name;
|
||||
unsigned char st_info;
|
||||
unsigned char st_other;
|
||||
Elf_Half st_shndx;
|
||||
Elf64_Addr st_value;
|
||||
Elf_Xword st_size;
|
||||
};
|
||||
|
||||
|
||||
#define ELF_ST_BIND(i) ((i)>>4)
|
||||
#define ELF_ST_TYPE(i) ((i)&0xf)
|
||||
#define ELF_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
|
||||
|
||||
#define ELF_ST_VISIBILITY(o) ((o)&0x3)
|
||||
|
||||
|
||||
// Relocation entries
|
||||
struct Elf32_Rel {
|
||||
Elf32_Addr r_offset;
|
||||
Elf_Word r_info;
|
||||
};
|
||||
|
||||
struct Elf32_Rela {
|
||||
Elf32_Addr r_offset;
|
||||
Elf_Word r_info;
|
||||
Elf_Sword r_addend;
|
||||
};
|
||||
|
||||
struct Elf64_Rel {
|
||||
Elf64_Addr r_offset;
|
||||
Elf_Xword r_info;
|
||||
};
|
||||
|
||||
struct Elf64_Rela {
|
||||
Elf64_Addr r_offset;
|
||||
Elf_Xword r_info;
|
||||
Elf_Sxword r_addend;
|
||||
};
|
||||
|
||||
|
||||
#define ELF32_R_SYM(i) ((i)>>8)
|
||||
#define ELF32_R_TYPE(i) ((unsigned char)(i))
|
||||
#define ELF32_R_INFO(s,t) (((s)<<8 )+(unsigned char)(t))
|
||||
|
||||
#define ELF64_R_SYM(i) ((i)>>32)
|
||||
#define ELF64_R_TYPE(i) ((i)&0xffffffffL)
|
||||
#define ELF64_R_INFO(s,t) ((((int64_t)(s))<<32)+((t)&0xffffffffL))
|
||||
|
||||
// Dynamic structure
|
||||
struct Elf32_Dyn {
|
||||
Elf_Sword d_tag;
|
||||
union {
|
||||
Elf_Word d_val;
|
||||
Elf32_Addr d_ptr;
|
||||
} d_un;
|
||||
};
|
||||
|
||||
struct Elf64_Dyn {
|
||||
Elf_Sxword d_tag;
|
||||
union {
|
||||
Elf_Xword d_val;
|
||||
Elf64_Addr d_ptr;
|
||||
} d_un;
|
||||
};
|
||||
|
||||
} // namespace ELFIO
|
||||
} // namespace amd
|
||||
|
||||
#endif // ELFTYPES_H
|
||||
@@ -0,0 +1,955 @@
|
||||
/*
|
||||
Copyright (C) 2001-2015 by Serge Lamikhov-Center
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef ELFIO_HPP
|
||||
#define ELFIO_HPP
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning ( push )
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4355)
|
||||
#pragma warning(disable:4244)
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <iterator>
|
||||
|
||||
#include <elfio/elf_types.hpp>
|
||||
#include <elfio/elfio_utils.hpp>
|
||||
#include <elfio/elfio_header.hpp>
|
||||
#include <elfio/elfio_section.hpp>
|
||||
#include <elfio/elfio_segment.hpp>
|
||||
#include <elfio/elfio_strings.hpp>
|
||||
|
||||
#define ELFIO_HEADER_ACCESS_GET( TYPE, FNAME ) \
|
||||
TYPE \
|
||||
get_##FNAME() const \
|
||||
{ \
|
||||
return header? header->get_##FNAME() : 0; \
|
||||
}
|
||||
|
||||
#define ELFIO_HEADER_ACCESS_GET_SET( TYPE, FNAME ) \
|
||||
TYPE \
|
||||
get_##FNAME() const \
|
||||
{ \
|
||||
return header? header->get_##FNAME() : 0; \
|
||||
} \
|
||||
void \
|
||||
set_##FNAME( TYPE val ) \
|
||||
{ \
|
||||
if (header) { \
|
||||
header->set_##FNAME( val ); \
|
||||
} \
|
||||
} \
|
||||
|
||||
namespace amd {
|
||||
namespace ELFIO {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class elfio
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
elfio() : sections( this ), segments( this )
|
||||
{
|
||||
header = 0;
|
||||
current_file_pos = 0;
|
||||
create( ELFCLASS32, ELFDATA2LSB );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
~elfio()
|
||||
{
|
||||
clean();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void create( unsigned char file_class, unsigned char encoding )
|
||||
{
|
||||
clean();
|
||||
convertor.setup( encoding );
|
||||
header = create_header( file_class, encoding );
|
||||
create_mandatory_sections();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool load( const std::string& file_name )
|
||||
{
|
||||
std::ifstream stream;
|
||||
stream.open( file_name.c_str(), std::ios::in | std::ios::binary );
|
||||
if ( !stream ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return load(stream);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool load( std::istream &stream )
|
||||
{
|
||||
clean();
|
||||
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
// Read ELF file signature
|
||||
stream.read( reinterpret_cast<char*>( &e_ident ), sizeof( e_ident ) );
|
||||
|
||||
// Is it ELF file?
|
||||
if ( stream.gcount() != sizeof( e_ident ) ||
|
||||
e_ident[EI_MAG0] != ELFMAG0 ||
|
||||
e_ident[EI_MAG1] != ELFMAG1 ||
|
||||
e_ident[EI_MAG2] != ELFMAG2 ||
|
||||
e_ident[EI_MAG3] != ELFMAG3 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ( e_ident[EI_CLASS] != ELFCLASS64 ) &&
|
||||
( e_ident[EI_CLASS] != ELFCLASS32 )) {
|
||||
return false;
|
||||
}
|
||||
|
||||
convertor.setup( e_ident[EI_DATA] );
|
||||
header = create_header( e_ident[EI_CLASS], e_ident[EI_DATA] );
|
||||
if ( 0 == header ) {
|
||||
return false;
|
||||
}
|
||||
if ( !header->load( stream ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
load_sections( stream );
|
||||
bool is_still_good = load_segments( stream );
|
||||
return is_still_good;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool save( const std::string& file_name )
|
||||
{
|
||||
std::ofstream stream;
|
||||
stream.open( file_name.c_str(), std::ios::out | std::ios::binary );
|
||||
if ( !stream ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return save(stream);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool save( std::ostream &stream )
|
||||
{
|
||||
if ( !stream || !header) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_still_good = true;
|
||||
// Define layout specific header fields
|
||||
// The position of the segment table is fixed after the header.
|
||||
// The position of the section table is variable and needs to be fixed
|
||||
// before saving.
|
||||
header->set_segments_num( segments.size() );
|
||||
header->set_segments_offset( segments.size() ? header->get_header_size() : 0 );
|
||||
header->set_sections_num( sections.size() );
|
||||
header->set_sections_offset( 0 );
|
||||
|
||||
// Layout the first section right after the segment table
|
||||
current_file_pos = header->get_header_size() +
|
||||
header->get_segment_entry_size() * header->get_segments_num();
|
||||
|
||||
calc_segment_alignment();
|
||||
|
||||
is_still_good = layout_segments_and_their_sections();
|
||||
is_still_good = is_still_good && layout_sections_without_segments();
|
||||
is_still_good = is_still_good && layout_section_table();
|
||||
|
||||
is_still_good = is_still_good && save_header( stream );
|
||||
is_still_good = is_still_good && save_sections( stream );
|
||||
is_still_good = is_still_good && save_segments( stream );
|
||||
|
||||
return is_still_good;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ELF header access functions
|
||||
ELFIO_HEADER_ACCESS_GET( unsigned char, class );
|
||||
ELFIO_HEADER_ACCESS_GET( unsigned char, elf_version );
|
||||
ELFIO_HEADER_ACCESS_GET( unsigned char, encoding );
|
||||
ELFIO_HEADER_ACCESS_GET( Elf_Word, version );
|
||||
ELFIO_HEADER_ACCESS_GET( Elf_Half, header_size );
|
||||
ELFIO_HEADER_ACCESS_GET( Elf_Half, section_entry_size );
|
||||
ELFIO_HEADER_ACCESS_GET( Elf_Half, segment_entry_size );
|
||||
|
||||
ELFIO_HEADER_ACCESS_GET_SET( unsigned char, os_abi );
|
||||
ELFIO_HEADER_ACCESS_GET_SET( unsigned char, abi_version );
|
||||
ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, type );
|
||||
ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, machine );
|
||||
ELFIO_HEADER_ACCESS_GET_SET( Elf_Word, flags );
|
||||
ELFIO_HEADER_ACCESS_GET_SET( Elf64_Addr, entry );
|
||||
ELFIO_HEADER_ACCESS_GET_SET( Elf64_Off, sections_offset );
|
||||
ELFIO_HEADER_ACCESS_GET_SET( Elf64_Off, segments_offset );
|
||||
ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, section_name_str_index );
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const endianess_convertor& get_convertor() const
|
||||
{
|
||||
return convertor;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Xword get_default_entry_size( Elf_Word section_type ) const
|
||||
{
|
||||
switch( section_type ) {
|
||||
case SHT_RELA:
|
||||
if ( header->get_class() == ELFCLASS64 ) {
|
||||
return sizeof( Elf64_Rela );
|
||||
}
|
||||
else {
|
||||
return sizeof( Elf32_Rela );
|
||||
}
|
||||
case SHT_REL:
|
||||
if ( header->get_class() == ELFCLASS64 ) {
|
||||
return sizeof( Elf64_Rel );
|
||||
}
|
||||
else {
|
||||
return sizeof( Elf32_Rel );
|
||||
}
|
||||
case SHT_SYMTAB:
|
||||
if ( header->get_class() == ELFCLASS64 ) {
|
||||
return sizeof( Elf64_Sym );
|
||||
}
|
||||
else {
|
||||
return sizeof( Elf32_Sym );
|
||||
}
|
||||
case SHT_DYNAMIC:
|
||||
if ( header->get_class() == ELFCLASS64 ) {
|
||||
return sizeof( Elf64_Dyn );
|
||||
}
|
||||
else {
|
||||
return sizeof( Elf32_Dyn );
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
bool is_offset_in_section( Elf64_Off offset, const section* sec ) const {
|
||||
return offset >= sec->get_offset() && offset < sec->get_offset()+sec->get_size();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
public:
|
||||
|
||||
//! returns an empty string if no problems are detected,
|
||||
//! or a string containing an error message if problems are found
|
||||
std::string validate() const {
|
||||
|
||||
// check for overlapping sections in the file
|
||||
for ( int i = 0; i < sections.size(); ++i) {
|
||||
for ( int j = i+1; j < sections.size(); ++j ) {
|
||||
const section* a = sections[i];
|
||||
const section* b = sections[j];
|
||||
if ( !(a->get_type() & SHT_NOBITS)
|
||||
&& !(b->get_type() & SHT_NOBITS)
|
||||
&& (a->get_size() > 0)
|
||||
&& (b->get_size() > 0)
|
||||
&& (a->get_offset() > 0)
|
||||
&& (b->get_offset() > 0)) {
|
||||
if ( is_offset_in_section( a->get_offset(), b )
|
||||
|| is_offset_in_section( a->get_offset()+a->get_size()-1, b )
|
||||
|| is_offset_in_section( b->get_offset(), a )
|
||||
|| is_offset_in_section( b->get_offset()+b->get_size()-1, a )) {
|
||||
return "Sections " + a->get_name() + " and " + b->get_name() + " overlap in file";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// more checks to be added here...
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void clean()
|
||||
{
|
||||
delete header;
|
||||
header = 0;
|
||||
|
||||
std::vector<section*>::const_iterator it;
|
||||
for ( it = sections_.begin(); it != sections_.end(); ++it ) {
|
||||
delete *it;
|
||||
}
|
||||
sections_.clear();
|
||||
|
||||
std::vector<segment*>::const_iterator it1;
|
||||
for ( it1 = segments_.begin(); it1 != segments_.end(); ++it1 ) {
|
||||
delete *it1;
|
||||
}
|
||||
segments_.clear();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
//------------------------------------------------------------------------------
|
||||
elf_header* create_header( unsigned char file_class, unsigned char encoding )
|
||||
{
|
||||
elf_header* new_header = 0;
|
||||
|
||||
if ( file_class == ELFCLASS64 ) {
|
||||
new_header = new elf_header_impl< Elf64_Ehdr >( &convertor,
|
||||
encoding );
|
||||
}
|
||||
else if ( file_class == ELFCLASS32 ) {
|
||||
new_header = new elf_header_impl< Elf32_Ehdr >( &convertor,
|
||||
encoding );
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return new_header;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
section* create_section()
|
||||
{
|
||||
section* new_section;
|
||||
unsigned char file_class = get_class();
|
||||
|
||||
if ( file_class == ELFCLASS64 ) {
|
||||
new_section = new section_impl<Elf64_Shdr>( &convertor );
|
||||
}
|
||||
else if ( file_class == ELFCLASS32 ) {
|
||||
new_section = new section_impl<Elf32_Shdr>( &convertor );
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
new_section->set_index( (Elf_Half)sections_.size() );
|
||||
sections_.push_back( new_section );
|
||||
|
||||
return new_section;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
segment* create_segment()
|
||||
{
|
||||
segment* new_segment;
|
||||
unsigned char file_class = header->get_class();
|
||||
|
||||
if ( file_class == ELFCLASS64 ) {
|
||||
new_segment = new segment_impl<Elf64_Phdr>( &convertor );
|
||||
}
|
||||
else if ( file_class == ELFCLASS32 ) {
|
||||
new_segment = new segment_impl<Elf32_Phdr>( &convertor );
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
new_segment->set_index( (Elf_Half)segments_.size() );
|
||||
segments_.push_back( new_segment );
|
||||
|
||||
return new_segment;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void create_mandatory_sections()
|
||||
{
|
||||
// Create null section without calling to 'add_section' as no string
|
||||
// section containing section names exists yet
|
||||
section* sec0 = create_section();
|
||||
sec0->set_index( 0 );
|
||||
sec0->set_name( "" );
|
||||
sec0->set_name_string_offset( 0 );
|
||||
|
||||
set_section_name_str_index( 1 );
|
||||
section* shstrtab = sections.add( ".shstrtab" );
|
||||
shstrtab->set_type( SHT_STRTAB );
|
||||
shstrtab->set_addr_align( 1 );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Half load_sections( std::istream& stream )
|
||||
{
|
||||
Elf_Half entry_size = header->get_section_entry_size();
|
||||
Elf_Half num = header->get_sections_num();
|
||||
Elf64_Off offset = header->get_sections_offset();
|
||||
|
||||
for ( Elf_Half i = 0; i < num; ++i ) {
|
||||
section* sec = create_section();
|
||||
sec->load( stream, (std::streamoff)offset + i * entry_size );
|
||||
sec->set_index( i );
|
||||
// To mark that the section is not permitted to reassign address
|
||||
// during layout calculation
|
||||
sec->set_address( sec->get_address() );
|
||||
}
|
||||
|
||||
Elf_Half shstrndx = get_section_name_str_index();
|
||||
|
||||
if ( SHN_UNDEF != shstrndx ) {
|
||||
string_section_accessor str_reader( sections[shstrndx] );
|
||||
for ( Elf_Half i = 0; i < num; ++i ) {
|
||||
Elf_Word section_offset = sections[i]->get_name_string_offset();
|
||||
const char* p = str_reader.get_string( section_offset );
|
||||
if ( p != 0 ) {
|
||||
sections[i]->set_name( p );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! Checks whether the addresses of the section entirely fall within the given segment.
|
||||
//! It doesn't matter if the addresses are memory addresses, or file offsets,
|
||||
//! they just need to be in the same address space
|
||||
bool is_sect_in_seg ( Elf64_Off sect_begin, Elf_Xword sect_size, Elf64_Off seg_begin, Elf64_Off seg_end ) {
|
||||
return seg_begin <= sect_begin
|
||||
&& sect_begin + sect_size <= seg_end
|
||||
&& sect_begin < seg_end; // this is important criteria when sect_size == 0
|
||||
// Example: seg_begin=10, seg_end=12 (-> covering the bytes 10 and 11)
|
||||
// sect_begin=12, sect_size=0 -> shall return false!
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool load_segments( std::istream& stream )
|
||||
{
|
||||
Elf_Half entry_size = header->get_segment_entry_size();
|
||||
Elf_Half num = header->get_segments_num();
|
||||
Elf64_Off offset = header->get_segments_offset();
|
||||
|
||||
for ( Elf_Half i = 0; i < num; ++i ) {
|
||||
segment* seg;
|
||||
unsigned char file_class = header->get_class();
|
||||
|
||||
if ( file_class == ELFCLASS64 ) {
|
||||
seg = new segment_impl<Elf64_Phdr>( &convertor );
|
||||
}
|
||||
else if ( file_class == ELFCLASS32 ) {
|
||||
seg = new segment_impl<Elf32_Phdr>( &convertor );
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
seg->load( stream, (std::streamoff)offset + i * entry_size );
|
||||
seg->set_index( i );
|
||||
|
||||
// Add sections to the segments (similar to readelfs algorithm)
|
||||
Elf64_Off segBaseOffset = seg->get_offset();
|
||||
Elf64_Off segEndOffset = segBaseOffset + seg->get_file_size();
|
||||
Elf64_Off segVBaseAddr = seg->get_virtual_address();
|
||||
Elf64_Off segVEndAddr = segVBaseAddr + seg->get_memory_size();
|
||||
for( Elf_Half j = 0; j < sections.size(); ++j ) {
|
||||
const section* psec = sections[j];
|
||||
|
||||
// SHF_ALLOC sections are matched based on the virtual address
|
||||
// otherwise the file offset is matched
|
||||
if( psec->get_flags() & SHF_ALLOC
|
||||
? is_sect_in_seg( psec->get_address(), psec->get_size(), segVBaseAddr, segVEndAddr )
|
||||
: is_sect_in_seg( psec->get_offset(), psec->get_size(), segBaseOffset, segEndOffset )) {
|
||||
// Alignment of segment shall not be updated, to preserve original value
|
||||
// It will be re-calculated on saving.
|
||||
seg->add_section_index( psec->get_index(), 0 );
|
||||
}
|
||||
}
|
||||
|
||||
// Add section into the segments' container
|
||||
segments_.push_back( seg );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool save_header( std::ostream& stream )
|
||||
{
|
||||
return header->save( stream );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool save_sections( std::ostream& stream )
|
||||
{
|
||||
for ( unsigned int i = 0; i < sections_.size(); ++i ) {
|
||||
section *sec = sections_.at(i);
|
||||
|
||||
std::streampos headerPosition =
|
||||
(std::streamoff)header->get_sections_offset() +
|
||||
header->get_section_entry_size() * sec->get_index();
|
||||
|
||||
sec->save(stream,headerPosition,sec->get_offset());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool save_segments( std::ostream& stream )
|
||||
{
|
||||
for ( unsigned int i = 0; i < segments_.size(); ++i ) {
|
||||
segment *seg = segments_.at(i);
|
||||
|
||||
std::streampos headerPosition = header->get_segments_offset() +
|
||||
header->get_segment_entry_size()*seg->get_index();
|
||||
|
||||
seg->save( stream, headerPosition, seg->get_offset() );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool is_section_without_segment( unsigned int section_index )
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
for ( unsigned int j = 0; !found && ( j < segments.size() ); ++j ) {
|
||||
for ( unsigned int k = 0;
|
||||
!found && ( k < segments[j]->get_sections_num() );
|
||||
++k ) {
|
||||
found = segments[j]->get_section_index_at( k ) == section_index;
|
||||
}
|
||||
}
|
||||
|
||||
return !found;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool is_subsequence_of( segment* seg1, segment* seg2 )
|
||||
{
|
||||
// Return 'true' if sections of seg1 are a subset of sections in seg2
|
||||
const std::vector<Elf_Half>& sections1 = seg1->get_sections();
|
||||
const std::vector<Elf_Half>& sections2 = seg2->get_sections();
|
||||
|
||||
bool found = false;
|
||||
if ( sections1.size() < sections2.size() ) {
|
||||
found = std::includes( sections2.begin(), sections2.end(),
|
||||
sections1.begin(), sections1.end() );
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
std::vector<segment*> get_ordered_segments( )
|
||||
{
|
||||
std::vector<segment*> res;
|
||||
std::deque<segment*> worklist;
|
||||
|
||||
res.reserve(segments.size());
|
||||
std::copy( segments_.begin(), segments_.end(),
|
||||
std::back_inserter( worklist )) ;
|
||||
|
||||
// Bring the segments which start at address 0 to the front
|
||||
size_t nextSlot = 0;
|
||||
for( size_t i = 0; i < worklist.size(); ++i ) {
|
||||
if( i != nextSlot && worklist[i]->is_offset_initialized()
|
||||
&& worklist[i]->get_offset() == 0 ) {
|
||||
if (worklist[nextSlot]->get_offset() == 0) {
|
||||
++nextSlot;
|
||||
}
|
||||
std::swap(worklist[i],worklist[nextSlot]);
|
||||
++nextSlot;
|
||||
}
|
||||
}
|
||||
|
||||
while ( !worklist.empty() ) {
|
||||
segment *seg = worklist.front();
|
||||
worklist.pop_front();
|
||||
|
||||
size_t i = 0;
|
||||
for ( ; i < worklist.size(); ++i ) {
|
||||
if ( is_subsequence_of( seg, worklist[i] ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( i < worklist.size() )
|
||||
worklist.push_back(seg);
|
||||
else
|
||||
res.push_back(seg);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool layout_sections_without_segments( )
|
||||
{
|
||||
for ( unsigned int i = 0; i < sections_.size(); ++i ) {
|
||||
if ( is_section_without_segment( i ) ) {
|
||||
section *sec = sections_[i];
|
||||
|
||||
Elf_Xword section_align = sec->get_addr_align();
|
||||
if ( section_align > 1 && current_file_pos % section_align != 0 ) {
|
||||
current_file_pos += section_align -
|
||||
current_file_pos % section_align;
|
||||
}
|
||||
|
||||
if ( 0 != sec->get_index() )
|
||||
sec->set_offset(current_file_pos);
|
||||
|
||||
if ( SHT_NOBITS != sec->get_type() &&
|
||||
SHT_NULL != sec->get_type() ) {
|
||||
current_file_pos += sec->get_size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void calc_segment_alignment( )
|
||||
{
|
||||
for( std::vector<segment*>::iterator s = segments_.begin(); s != segments_.end(); ++s ) {
|
||||
segment* seg = *s;
|
||||
for ( int i = 0; i < seg->get_sections_num(); ++i ) {
|
||||
section* sect = sections_[ seg->get_section_index_at(i) ];
|
||||
if ( sect->get_addr_align() > seg->get_align() ) {
|
||||
seg->set_align( sect->get_addr_align() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool layout_segments_and_their_sections( )
|
||||
{
|
||||
std::vector<segment*> worklist;
|
||||
std::vector<bool> section_generated(sections.size(),false);
|
||||
|
||||
// Get segments in a order in where segments which contain a
|
||||
// sub sequence of other segments are located at the end
|
||||
worklist = get_ordered_segments();
|
||||
|
||||
for ( unsigned int i = 0; i < worklist.size(); ++i ) {
|
||||
Elf_Xword segment_memory = 0;
|
||||
Elf_Xword segment_filesize = 0;
|
||||
Elf_Xword seg_start_pos = current_file_pos;
|
||||
segment* seg = worklist[i];
|
||||
|
||||
// Special case: PHDR segment
|
||||
// This segment contains the program headers but no sections
|
||||
if ( seg->get_type() == PT_PHDR && seg->get_sections_num() == 0 ) {
|
||||
seg_start_pos = header->get_segments_offset();
|
||||
segment_memory = segment_filesize =
|
||||
header->get_segment_entry_size() * header->get_segments_num();
|
||||
}
|
||||
// Special case:
|
||||
else if ( seg->is_offset_initialized() && seg->get_offset() == 0 ) {
|
||||
seg_start_pos = 0;
|
||||
if ( seg->get_sections_num() ) {
|
||||
segment_memory = segment_filesize = current_file_pos;
|
||||
}
|
||||
}
|
||||
// New segments with not generated sections
|
||||
// have to be aligned
|
||||
else if ( seg->get_sections_num()
|
||||
&& !section_generated[seg->get_section_index_at( 0 )] ) {
|
||||
Elf_Xword align = seg->get_align() > 0 ? seg->get_align() : 1;
|
||||
Elf64_Off cur_page_alignment = current_file_pos % align;
|
||||
Elf64_Off req_page_alignment = seg->get_virtual_address() % align;
|
||||
Elf64_Off error = req_page_alignment - cur_page_alignment;
|
||||
|
||||
current_file_pos += ( seg->get_align() + error ) % align;
|
||||
seg_start_pos = current_file_pos;
|
||||
}
|
||||
else if ( seg->get_sections_num() ) {
|
||||
seg_start_pos = sections[seg->get_section_index_at( 0 )]->get_offset();
|
||||
}
|
||||
|
||||
// Write segment's data
|
||||
for ( unsigned int j = 0; j < seg->get_sections_num(); ++j ) {
|
||||
Elf_Half index = seg->get_section_index_at( j );
|
||||
|
||||
section* sec = sections[ index ];
|
||||
|
||||
// The NULL section is always generated
|
||||
if ( SHT_NULL == sec->get_type()) {
|
||||
section_generated[index] = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
Elf_Xword secAlign = 0;
|
||||
// Fix up the alignment
|
||||
if ( !section_generated[index] && sec->is_address_initialized()
|
||||
&& SHT_NOBITS != sec->get_type()
|
||||
&& SHT_NULL != sec->get_type()
|
||||
&& 0 != sec->get_size() ) {
|
||||
// Align the sections based on the virtual addresses
|
||||
// when possible (this is what matters for execution)
|
||||
Elf64_Off req_offset = sec->get_address() - seg->get_virtual_address();
|
||||
Elf64_Off cur_offset = current_file_pos - seg_start_pos;
|
||||
if ( req_offset < cur_offset) {
|
||||
// something has gone awfully wrong, abort!
|
||||
// secAlign would turn out negative, seeking backwards and overwriting previous data
|
||||
return false;
|
||||
}
|
||||
secAlign = req_offset - cur_offset;
|
||||
}
|
||||
else if (!section_generated[index] && !sec->is_address_initialized() ) {
|
||||
// If no address has been specified then only the section
|
||||
// alignment constraint has to be matched
|
||||
Elf_Xword align = sec->get_addr_align();
|
||||
if (align == 0) {
|
||||
align = 1;
|
||||
}
|
||||
Elf64_Off error = current_file_pos % align;
|
||||
secAlign = ( align - error ) % align;
|
||||
}
|
||||
else if (section_generated[index] ) {
|
||||
// Alignment for already generated sections
|
||||
secAlign = sec->get_offset() - seg_start_pos - segment_filesize;
|
||||
}
|
||||
|
||||
// Determine the segment file and memory sizes
|
||||
// Special case .tbss section (NOBITS) in non TLS segment
|
||||
if ( (sec->get_flags() & SHF_ALLOC)
|
||||
&& !( (sec->get_flags() & SHF_TLS) && (seg->get_type() != PT_TLS)
|
||||
&& ( SHT_NOBITS == sec->get_type())) )
|
||||
segment_memory += sec->get_size() + secAlign;
|
||||
if ( SHT_NOBITS != sec->get_type() && SHT_NULL != sec->get_type() )
|
||||
segment_filesize += sec->get_size() + secAlign;
|
||||
|
||||
// Nothing to be done when generating nested segments
|
||||
if(section_generated[index]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
current_file_pos += secAlign;
|
||||
|
||||
// Set the section addresses when missing
|
||||
if ( !sec->is_address_initialized() )
|
||||
sec->set_address( seg->get_virtual_address()
|
||||
+ current_file_pos - seg_start_pos);
|
||||
|
||||
if ( 0 != sec->get_index() )
|
||||
sec->set_offset(current_file_pos);
|
||||
|
||||
if ( SHT_NOBITS != sec->get_type() && SHT_NULL != sec->get_type() )
|
||||
current_file_pos += sec->get_size();
|
||||
section_generated[index] = true;
|
||||
}
|
||||
|
||||
seg->set_file_size( segment_filesize );
|
||||
|
||||
// If we already have a memory size from loading an elf file (value > 0),
|
||||
// it must not shrink!
|
||||
// Memory size may be bigger than file size and it is the loader's job to do something
|
||||
// with the surplus bytes in memory, like initializing them with a defined value.
|
||||
if ( seg->get_memory_size() < segment_memory ) {
|
||||
seg->set_memory_size( segment_memory );
|
||||
}
|
||||
|
||||
seg->set_offset(seg_start_pos);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool layout_section_table()
|
||||
{
|
||||
// Simply place the section table at the end for now
|
||||
Elf64_Off alignmentError = current_file_pos % 4;
|
||||
current_file_pos += ( 4 - alignmentError ) % 4;
|
||||
header->set_sections_offset(current_file_pos);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
public:
|
||||
friend class Sections;
|
||||
class Sections {
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
Sections( elfio* parent_ ) :
|
||||
parent( parent_ )
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Half size() const
|
||||
{
|
||||
return (Elf_Half)parent->sections_.size();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
section* operator[]( unsigned int index ) const
|
||||
{
|
||||
section* sec = 0;
|
||||
|
||||
if ( index < parent->sections_.size() ) {
|
||||
sec = parent->sections_[index];
|
||||
}
|
||||
|
||||
return sec;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
section* operator[]( const std::string& name ) const
|
||||
{
|
||||
section* sec = 0;
|
||||
|
||||
std::vector<section*>::const_iterator it;
|
||||
for ( it = parent->sections_.begin();
|
||||
it != parent->sections_.end();
|
||||
++it ) {
|
||||
if ( (*it)->get_name() == name ) {
|
||||
sec = *it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sec;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
section* add( const std::string& name )
|
||||
{
|
||||
section* new_section = parent->create_section();
|
||||
new_section->set_name( name );
|
||||
|
||||
Elf_Half str_index = parent->get_section_name_str_index();
|
||||
section* string_table( parent->sections_[str_index] );
|
||||
string_section_accessor str_writer( string_table );
|
||||
Elf_Word pos = str_writer.add_string( name );
|
||||
new_section->set_name_string_offset( pos );
|
||||
|
||||
return new_section;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
std::vector<section*>::iterator begin() {
|
||||
return parent->sections_.begin();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
std::vector<section*>::iterator end() {
|
||||
return parent->sections_.end();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
std::vector<section*>::const_iterator begin() const {
|
||||
return parent->sections_.cbegin();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
std::vector<section*>::const_iterator end() const {
|
||||
return parent->sections_.cend();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
elfio* parent;
|
||||
} sections;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
public:
|
||||
friend class Segments;
|
||||
class Segments {
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
Segments( elfio* parent_ ) :
|
||||
parent( parent_ )
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Half size() const
|
||||
{
|
||||
return (Elf_Half)parent->segments_.size();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
segment* operator[]( unsigned int index ) const
|
||||
{
|
||||
return parent->segments_[index];
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
segment* add()
|
||||
{
|
||||
return parent->create_segment();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
std::vector<segment*>::iterator begin() {
|
||||
return parent->segments_.begin();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
std::vector<segment*>::iterator end() {
|
||||
return parent->segments_.end();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
std::vector<segment*>::const_iterator begin() const {
|
||||
return parent->segments_.cbegin();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
std::vector<segment*>::const_iterator end() const {
|
||||
return parent->segments_.cend();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
elfio* parent;
|
||||
} segments;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
elf_header* header;
|
||||
std::vector<section*> sections_;
|
||||
std::vector<segment*> segments_;
|
||||
endianess_convertor convertor;
|
||||
|
||||
Elf_Xword current_file_pos;
|
||||
};
|
||||
|
||||
} // namespace ELFIO
|
||||
} // namespace amd
|
||||
|
||||
#include <elfio/elfio_symbols.hpp>
|
||||
#include <elfio/elfio_note.hpp>
|
||||
#include <elfio/elfio_relocation.hpp>
|
||||
#include <elfio/elfio_dynamic.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning ( pop )
|
||||
#endif
|
||||
|
||||
#endif // ELFIO_HPP
|
||||
@@ -0,0 +1,977 @@
|
||||
/*
|
||||
Copyright (C) 2001-2015 by Serge Lamikhov-Center
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef ELFIO_DUMP_HPP
|
||||
#define ELFIO_DUMP_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <elfio/elfio.hpp>
|
||||
|
||||
namespace amd {
|
||||
namespace ELFIO {
|
||||
|
||||
static struct class_table_t {
|
||||
const char key;
|
||||
const char* str;
|
||||
} class_table [] =
|
||||
{
|
||||
{ ELFCLASS32, "ELF32" },
|
||||
{ ELFCLASS64, "ELF64" },
|
||||
};
|
||||
|
||||
|
||||
static struct endian_table_t {
|
||||
const char key;
|
||||
const char* str;
|
||||
} endian_table [] =
|
||||
{
|
||||
{ ELFDATANONE, "None" },
|
||||
{ ELFDATA2LSB, "Little endian" },
|
||||
{ ELFDATA2MSB, "Big endian" },
|
||||
};
|
||||
|
||||
|
||||
static struct version_table_t {
|
||||
const Elf64_Word key;
|
||||
const char* str;
|
||||
} version_table [] =
|
||||
{
|
||||
{ EV_NONE , "None" },
|
||||
{ EV_CURRENT, "Current" },
|
||||
};
|
||||
|
||||
|
||||
static struct type_table_t {
|
||||
const Elf32_Half key;
|
||||
const char* str;
|
||||
} type_table [] =
|
||||
{
|
||||
{ ET_NONE, "No file type" },
|
||||
{ ET_REL , "Relocatable file" },
|
||||
{ ET_EXEC, "Executable file" },
|
||||
{ ET_DYN , "Shared object file" },
|
||||
{ ET_CORE, "Core file" },
|
||||
};
|
||||
|
||||
|
||||
static struct machine_table_t {
|
||||
const Elf64_Half key;
|
||||
const char* str;
|
||||
} machine_table [] =
|
||||
{
|
||||
{ EM_NONE , "No machine" },
|
||||
{ EM_M32 , "AT&T WE 32100" },
|
||||
{ EM_SPARC , "SUN SPARC" },
|
||||
{ EM_386 , "Intel 80386" },
|
||||
{ EM_68K , "Motorola m68k family" },
|
||||
{ EM_88K , "Motorola m88k family" },
|
||||
{ EM_486 , "Intel 80486// Reserved for future use" },
|
||||
{ EM_860 , "Intel 80860" },
|
||||
{ EM_MIPS , "MIPS R3000 (officially, big-endian only)" },
|
||||
{ EM_S370 , "IBM System/370" },
|
||||
{ EM_MIPS_RS3_LE , "MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated" },
|
||||
{ EM_res011 , "Reserved" },
|
||||
{ EM_res012 , "Reserved" },
|
||||
{ EM_res013 , "Reserved" },
|
||||
{ EM_res014 , "Reserved" },
|
||||
{ EM_PARISC , "HPPA" },
|
||||
{ EM_res016 , "Reserved" },
|
||||
{ EM_VPP550 , "Fujitsu VPP500" },
|
||||
{ EM_SPARC32PLUS , "Sun's v8plus" },
|
||||
{ EM_960 , "Intel 80960" },
|
||||
{ EM_PPC , "PowerPC" },
|
||||
{ EM_PPC64 , "64-bit PowerPC" },
|
||||
{ EM_S390 , "IBM S/390" },
|
||||
{ EM_SPU , "Sony/Toshiba/IBM SPU" },
|
||||
{ EM_res024 , "Reserved" },
|
||||
{ EM_res025 , "Reserved" },
|
||||
{ EM_res026 , "Reserved" },
|
||||
{ EM_res027 , "Reserved" },
|
||||
{ EM_res028 , "Reserved" },
|
||||
{ EM_res029 , "Reserved" },
|
||||
{ EM_res030 , "Reserved" },
|
||||
{ EM_res031 , "Reserved" },
|
||||
{ EM_res032 , "Reserved" },
|
||||
{ EM_res033 , "Reserved" },
|
||||
{ EM_res034 , "Reserved" },
|
||||
{ EM_res035 , "Reserved" },
|
||||
{ EM_V800 , "NEC V800 series" },
|
||||
{ EM_FR20 , "Fujitsu FR20" },
|
||||
{ EM_RH32 , "TRW RH32" },
|
||||
{ EM_MCORE , "Motorola M*Core // May also be taken by Fujitsu MMA" },
|
||||
{ EM_RCE , "Old name for MCore" },
|
||||
{ EM_ARM , "ARM" },
|
||||
{ EM_OLD_ALPHA , "Digital Alpha" },
|
||||
{ EM_SH , "Renesas (formerly Hitachi) / SuperH SH" },
|
||||
{ EM_SPARCV9 , "SPARC v9 64-bit" },
|
||||
{ EM_TRICORE , "Siemens Tricore embedded processor" },
|
||||
{ EM_ARC , "ARC Cores" },
|
||||
{ EM_H8_300 , "Renesas (formerly Hitachi) H8/300" },
|
||||
{ EM_H8_300H , "Renesas (formerly Hitachi) H8/300H" },
|
||||
{ EM_H8S , "Renesas (formerly Hitachi) H8S" },
|
||||
{ EM_H8_500 , "Renesas (formerly Hitachi) H8/500" },
|
||||
{ EM_IA_64 , "Intel IA-64 Processor" },
|
||||
{ EM_MIPS_X , "Stanford MIPS-X" },
|
||||
{ EM_COLDFIRE , "Motorola Coldfire" },
|
||||
{ EM_68HC12 , "Motorola M68HC12" },
|
||||
{ EM_MMA , "Fujitsu Multimedia Accelerator" },
|
||||
{ EM_PCP , "Siemens PCP" },
|
||||
{ EM_NCPU , "Sony nCPU embedded RISC processor" },
|
||||
{ EM_NDR1 , "Denso NDR1 microprocesspr" },
|
||||
{ EM_STARCORE , "Motorola Star*Core processor" },
|
||||
{ EM_ME16 , "Toyota ME16 processor" },
|
||||
{ EM_ST100 , "STMicroelectronics ST100 processor" },
|
||||
{ EM_TINYJ , "Advanced Logic Corp. TinyJ embedded processor" },
|
||||
{ EM_X86_64 , "Advanced Micro Devices X86-64 processor" },
|
||||
{ EM_PDSP , "Sony DSP Processor" },
|
||||
{ EM_PDP10 , "Digital Equipment Corp. PDP-10" },
|
||||
{ EM_PDP11 , "Digital Equipment Corp. PDP-11" },
|
||||
{ EM_FX66 , "Siemens FX66 microcontroller" },
|
||||
{ EM_ST9PLUS , "STMicroelectronics ST9+ 8/16 bit microcontroller" },
|
||||
{ EM_ST7 , "STMicroelectronics ST7 8-bit microcontroller" },
|
||||
{ EM_68HC16 , "Motorola MC68HC16 Microcontroller" },
|
||||
{ EM_68HC11 , "Motorola MC68HC11 Microcontroller" },
|
||||
{ EM_68HC08 , "Motorola MC68HC08 Microcontroller" },
|
||||
{ EM_68HC05 , "Motorola MC68HC05 Microcontroller" },
|
||||
{ EM_SVX , "Silicon Graphics SVx" },
|
||||
{ EM_ST19 , "STMicroelectronics ST19 8-bit cpu" },
|
||||
{ EM_VAX , "Digital VAX" },
|
||||
{ EM_CRIS , "Axis Communications 32-bit embedded processor" },
|
||||
{ EM_JAVELIN , "Infineon Technologies 32-bit embedded cpu" },
|
||||
{ EM_FIREPATH , "Element 14 64-bit DSP processor" },
|
||||
{ EM_ZSP , "LSI Logic's 16-bit DSP processor" },
|
||||
{ EM_MMIX , "Donald Knuth's educational 64-bit processor" },
|
||||
{ EM_HUANY , "Harvard's machine-independent format" },
|
||||
{ EM_PRISM , "SiTera Prism" },
|
||||
{ EM_AVR , "Atmel AVR 8-bit microcontroller" },
|
||||
{ EM_FR30 , "Fujitsu FR30" },
|
||||
{ EM_D10V , "Mitsubishi D10V" },
|
||||
{ EM_D30V , "Mitsubishi D30V" },
|
||||
{ EM_V850 , "NEC v850" },
|
||||
{ EM_M32R , "Renesas M32R (formerly Mitsubishi M32R)" },
|
||||
{ EM_MN10300 , "Matsushita MN10300" },
|
||||
{ EM_MN10200 , "Matsushita MN10200" },
|
||||
{ EM_PJ , "picoJava" },
|
||||
{ EM_OPENRISC , "OpenRISC 32-bit embedded processor" },
|
||||
{ EM_ARC_A5 , "ARC Cores Tangent-A5" },
|
||||
{ EM_XTENSA , "Tensilica Xtensa Architecture" },
|
||||
{ EM_VIDEOCORE , "Alphamosaic VideoCore processor" },
|
||||
{ EM_TMM_GPP , "Thompson Multimedia General Purpose Processor" },
|
||||
{ EM_NS32K , "National Semiconductor 32000 series" },
|
||||
{ EM_TPC , "Tenor Network TPC processor" },
|
||||
{ EM_SNP1K , "Trebia SNP 1000 processor" },
|
||||
{ EM_ST200 , "STMicroelectronics ST200 microcontroller" },
|
||||
{ EM_IP2K , "Ubicom IP2022 micro controller" },
|
||||
{ EM_MAX , "MAX Processor" },
|
||||
{ EM_CR , "National Semiconductor CompactRISC" },
|
||||
{ EM_F2MC16 , "Fujitsu F2MC16" },
|
||||
{ EM_MSP430 , "TI msp430 micro controller" },
|
||||
{ EM_BLACKFIN , "ADI Blackfin" },
|
||||
{ EM_SE_C33 , "S1C33 Family of Seiko Epson processors" },
|
||||
{ EM_SEP , "Sharp embedded microprocessor" },
|
||||
{ EM_ARCA , "Arca RISC Microprocessor" },
|
||||
{ EM_UNICORE , "Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University" },
|
||||
{ EM_EXCESS , "eXcess: 16/32/64-bit configurable embedded CPU" },
|
||||
{ EM_DXP , "Icera Semiconductor Inc. Deep Execution Processor" },
|
||||
{ EM_ALTERA_NIOS2 , "Altera Nios II soft-core processor" },
|
||||
{ EM_CRX , "National Semiconductor CRX" },
|
||||
{ EM_XGATE , "Motorola XGATE embedded processor" },
|
||||
{ EM_C166 , "Infineon C16x/XC16x processor" },
|
||||
{ EM_M16C , "Renesas M16C series microprocessors" },
|
||||
{ EM_DSPIC30F , "Microchip Technology dsPIC30F Digital Signal Controller" },
|
||||
{ EM_CE , "Freescale Communication Engine RISC core" },
|
||||
{ EM_M32C , "Renesas M32C series microprocessors" },
|
||||
{ EM_res121 , "Reserved" },
|
||||
{ EM_res122 , "Reserved" },
|
||||
{ EM_res123 , "Reserved" },
|
||||
{ EM_res124 , "Reserved" },
|
||||
{ EM_res125 , "Reserved" },
|
||||
{ EM_res126 , "Reserved" },
|
||||
{ EM_res127 , "Reserved" },
|
||||
{ EM_res128 , "Reserved" },
|
||||
{ EM_res129 , "Reserved" },
|
||||
{ EM_res130 , "Reserved" },
|
||||
{ EM_TSK3000 , "Altium TSK3000 core" },
|
||||
{ EM_RS08 , "Freescale RS08 embedded processor" },
|
||||
{ EM_res133 , "Reserved" },
|
||||
{ EM_ECOG2 , "Cyan Technology eCOG2 microprocessor" },
|
||||
{ EM_SCORE , "Sunplus Score" },
|
||||
{ EM_SCORE7 , "Sunplus S+core7 RISC processor" },
|
||||
{ EM_DSP24 , "New Japan Radio (NJR) 24-bit DSP Processor" },
|
||||
{ EM_VIDEOCORE3 , "Broadcom VideoCore III processor" },
|
||||
{ EM_LATTICEMICO32, "RISC processor for Lattice FPGA architecture" },
|
||||
{ EM_SE_C17 , "Seiko Epson C17 family" },
|
||||
{ EM_TI_C6000 , "Texas Instruments TMS320C6000 DSP family" },
|
||||
{ EM_TI_C2000 , "Texas Instruments TMS320C2000 DSP family" },
|
||||
{ EM_TI_C5500 , "Texas Instruments TMS320C55x DSP family" },
|
||||
{ EM_res143 , "Reserved" },
|
||||
{ EM_res144 , "Reserved" },
|
||||
{ EM_res145 , "Reserved" },
|
||||
{ EM_res146 , "Reserved" },
|
||||
{ EM_res147 , "Reserved" },
|
||||
{ EM_res148 , "Reserved" },
|
||||
{ EM_res149 , "Reserved" },
|
||||
{ EM_res150 , "Reserved" },
|
||||
{ EM_res151 , "Reserved" },
|
||||
{ EM_res152 , "Reserved" },
|
||||
{ EM_res153 , "Reserved" },
|
||||
{ EM_res154 , "Reserved" },
|
||||
{ EM_res155 , "Reserved" },
|
||||
{ EM_res156 , "Reserved" },
|
||||
{ EM_res157 , "Reserved" },
|
||||
{ EM_res158 , "Reserved" },
|
||||
{ EM_res159 , "Reserved" },
|
||||
{ EM_MMDSP_PLUS , "STMicroelectronics 64bit VLIW Data Signal Processor" },
|
||||
{ EM_CYPRESS_M8C , "Cypress M8C microprocessor" },
|
||||
{ EM_R32C , "Renesas R32C series microprocessors" },
|
||||
{ EM_TRIMEDIA , "NXP Semiconductors TriMedia architecture family" },
|
||||
{ EM_QDSP6 , "QUALCOMM DSP6 Processor" },
|
||||
{ EM_8051 , "Intel 8051 and variants" },
|
||||
{ EM_STXP7X , "STMicroelectronics STxP7x family" },
|
||||
{ EM_NDS32 , "Andes Technology compact code size embedded RISC processor family" },
|
||||
{ EM_ECOG1 , "Cyan Technology eCOG1X family" },
|
||||
{ EM_ECOG1X , "Cyan Technology eCOG1X family" },
|
||||
{ EM_MAXQ30 , "Dallas Semiconductor MAXQ30 Core Micro-controllers" },
|
||||
{ EM_XIMO16 , "New Japan Radio (NJR) 16-bit DSP Processor" },
|
||||
{ EM_MANIK , "M2000 Reconfigurable RISC Microprocessor" },
|
||||
{ EM_CRAYNV2 , "Cray Inc. NV2 vector architecture" },
|
||||
{ EM_RX , "Renesas RX family" },
|
||||
{ EM_METAG , "Imagination Technologies META processor architecture" },
|
||||
{ EM_MCST_ELBRUS , "MCST Elbrus general purpose hardware architecture" },
|
||||
{ EM_ECOG16 , "Cyan Technology eCOG16 family" },
|
||||
{ EM_CR16 , "National Semiconductor CompactRISC 16-bit processor" },
|
||||
{ EM_ETPU , "Freescale Extended Time Processing Unit" },
|
||||
{ EM_SLE9X , "Infineon Technologies SLE9X core" },
|
||||
{ EM_L1OM , "Intel L1OM" },
|
||||
{ EM_INTEL181 , "Reserved by Intel" },
|
||||
{ EM_INTEL182 , "Reserved by Intel" },
|
||||
{ EM_res183 , "Reserved by ARM" },
|
||||
{ EM_res184 , "Reserved by ARM" },
|
||||
{ EM_AVR32 , "Atmel Corporation 32-bit microprocessor family" },
|
||||
{ EM_STM8 , "STMicroeletronics STM8 8-bit microcontroller" },
|
||||
{ EM_TILE64 , "Tilera TILE64 multicore architecture family" },
|
||||
{ EM_TILEPRO , "Tilera TILEPro multicore architecture family" },
|
||||
{ EM_MICROBLAZE , "Xilinx MicroBlaze 32-bit RISC soft processor core" },
|
||||
{ EM_CUDA , "NVIDIA CUDA architecture " },
|
||||
};
|
||||
|
||||
|
||||
static struct section_type_table_t {
|
||||
const Elf64_Half key;
|
||||
const char* str;
|
||||
} section_type_table [] =
|
||||
{
|
||||
{ SHT_NULL , "NULL" },
|
||||
{ SHT_PROGBITS , "PROGBITS" },
|
||||
{ SHT_SYMTAB , "SYMTAB" },
|
||||
{ SHT_STRTAB , "STRTAB" },
|
||||
{ SHT_RELA , "RELA" },
|
||||
{ SHT_HASH , "HASH" },
|
||||
{ SHT_DYNAMIC , "DYNAMIC" },
|
||||
{ SHT_NOTE , "NOTE" },
|
||||
{ SHT_NOBITS , "NOBITS" },
|
||||
{ SHT_REL , "REL" },
|
||||
{ SHT_SHLIB , "SHLIB" },
|
||||
{ SHT_DYNSYM , "DYNSYM" },
|
||||
{ SHT_INIT_ARRAY , "INIT_ARRAY" },
|
||||
{ SHT_FINI_ARRAY , "FINI_ARRAY" },
|
||||
{ SHT_PREINIT_ARRAY, "PREINIT_ARRAY" },
|
||||
{ SHT_GROUP , "GROUP" },
|
||||
{ SHT_SYMTAB_SHNDX , "SYMTAB_SHNDX " },
|
||||
};
|
||||
|
||||
|
||||
static struct segment_type_table_t {
|
||||
const Elf_Word key;
|
||||
const char* str;
|
||||
} segment_type_table [] =
|
||||
{
|
||||
{ PT_NULL , "NULL" },
|
||||
{ PT_LOAD , "LOAD" },
|
||||
{ PT_DYNAMIC, "DYNAMIC" },
|
||||
{ PT_INTERP , "INTERP" },
|
||||
{ PT_NOTE , "NOTE" },
|
||||
{ PT_SHLIB , "SHLIB" },
|
||||
{ PT_PHDR , "PHDR" },
|
||||
{ PT_TLS , "TLS" },
|
||||
};
|
||||
|
||||
|
||||
static struct segment_flag_table_t {
|
||||
const Elf_Word key;
|
||||
const char* str;
|
||||
} segment_flag_table [] =
|
||||
{
|
||||
{ 0, "" },
|
||||
{ 1, "X" },
|
||||
{ 2, "W" },
|
||||
{ 3, "WX" },
|
||||
{ 4, "R" },
|
||||
{ 5, "RX" },
|
||||
{ 6, "RW" },
|
||||
{ 7, "RWX" },
|
||||
};
|
||||
|
||||
|
||||
static struct symbol_bind_t {
|
||||
const Elf_Word key;
|
||||
const char* str;
|
||||
} symbol_bind_table [] =
|
||||
{
|
||||
{ STB_LOCAL , "LOCAL" },
|
||||
{ STB_GLOBAL , "GLOBAL" },
|
||||
{ STB_WEAK , "WEAK" },
|
||||
{ STB_LOOS , "LOOS" },
|
||||
{ STB_HIOS , "HIOS" },
|
||||
{ STB_MULTIDEF, "MULTIDEF" },
|
||||
{ STB_LOPROC , "LOPROC" },
|
||||
{ STB_HIPROC , "HIPROC" },
|
||||
};
|
||||
|
||||
|
||||
static struct symbol_type_t {
|
||||
const Elf_Word key;
|
||||
const char* str;
|
||||
} symbol_type_table [] =
|
||||
{
|
||||
{ STT_NOTYPE , "NOTYPE" },
|
||||
{ STT_OBJECT , "OBJECT" },
|
||||
{ STT_FUNC , "FUNC" },
|
||||
{ STT_SECTION, "SECTION" },
|
||||
{ STT_FILE , "FILE" },
|
||||
{ STT_COMMON , "COMMON" },
|
||||
{ STT_TLS , "TLS" },
|
||||
{ STT_LOOS , "LOOS" },
|
||||
{ STT_HIOS , "HIOS" },
|
||||
{ STT_LOPROC , "LOPROC" },
|
||||
{ STT_HIPROC , "HIPROC" },
|
||||
};
|
||||
|
||||
|
||||
static struct dynamic_tag_t {
|
||||
const Elf_Word key;
|
||||
const char* str;
|
||||
} dynamic_tag_table [] =
|
||||
{
|
||||
{ DT_NULL , "NULL" },
|
||||
{ DT_NEEDED , "NEEDED" },
|
||||
{ DT_PLTRELSZ , "PLTRELSZ" },
|
||||
{ DT_PLTGOT , "PLTGOT" },
|
||||
{ DT_HASH , "HASH" },
|
||||
{ DT_STRTAB , "STRTAB" },
|
||||
{ DT_SYMTAB , "SYMTAB" },
|
||||
{ DT_RELA , "RELA" },
|
||||
{ DT_RELASZ , "RELASZ" },
|
||||
{ DT_RELAENT , "RELAENT" },
|
||||
{ DT_STRSZ , "STRSZ" },
|
||||
{ DT_SYMENT , "SYMENT" },
|
||||
{ DT_INIT , "INIT" },
|
||||
{ DT_FINI , "FINI" },
|
||||
{ DT_SONAME , "SONAME" },
|
||||
{ DT_RPATH , "RPATH" },
|
||||
{ DT_SYMBOLIC , "SYMBOLIC" },
|
||||
{ DT_REL , "REL" },
|
||||
{ DT_RELSZ , "RELSZ" },
|
||||
{ DT_RELENT , "RELENT" },
|
||||
{ DT_PLTREL , "PLTREL" },
|
||||
{ DT_DEBUG , "DEBUG" },
|
||||
{ DT_TEXTREL , "TEXTREL" },
|
||||
{ DT_JMPREL , "JMPREL" },
|
||||
{ DT_BIND_NOW , "BIND_NOW" },
|
||||
{ DT_INIT_ARRAY , "INIT_ARRAY" },
|
||||
{ DT_FINI_ARRAY , "FINI_ARRAY" },
|
||||
{ DT_INIT_ARRAYSZ , "INIT_ARRAYSZ" },
|
||||
{ DT_FINI_ARRAYSZ , "FINI_ARRAYSZ" },
|
||||
{ DT_RUNPATH , "RUNPATH" },
|
||||
{ DT_FLAGS , "FLAGS" },
|
||||
{ DT_ENCODING , "ENCODING" },
|
||||
{ DT_PREINIT_ARRAY , "PREINIT_ARRAY" },
|
||||
{ DT_PREINIT_ARRAYSZ, "PREINIT_ARRAYSZ" },
|
||||
{ DT_MAXPOSTAGS , "MAXPOSTAGS" },
|
||||
};
|
||||
|
||||
static const ELFIO::Elf_Xword MAX_DATA_ENTRIES = 64;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class dump
|
||||
{
|
||||
#define DUMP_DEC_FORMAT( width ) std::setw(width) << std::setfill( ' ' ) << \
|
||||
std::dec << std::right
|
||||
#define DUMP_HEX_FORMAT( width ) std::setw(width) << std::setfill( '0' ) << \
|
||||
std::hex << std::right
|
||||
#define DUMP_STR_FORMAT( width ) std::setw(width) << std::setfill( ' ' ) << \
|
||||
std::hex << std::left
|
||||
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
header( std::ostream& out, const elfio& reader )
|
||||
{
|
||||
if (!reader.get_header_size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
out << "ELF Header" << std::endl << std::endl
|
||||
<< " Class: " << str_class( reader.get_class() ) << std::endl
|
||||
<< " Encoding: " << str_endian( reader.get_encoding() ) << std::endl
|
||||
<< " ELFVersion: " << str_version( reader.get_elf_version() ) << std::endl
|
||||
<< " Type: " << str_type( reader.get_type() ) << std::endl
|
||||
<< " Machine: " << str_machine( reader.get_machine() ) << std::endl
|
||||
<< " Version: " << str_version( reader.get_version() ) << std::endl
|
||||
<< " Entry: " << "0x" << std::hex << reader.get_entry() << std::endl
|
||||
<< " Flags: " << "0x" << std::hex << reader.get_flags() << std::endl
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
section_headers( std::ostream& out, const elfio& reader )
|
||||
{
|
||||
Elf_Half n = reader.sections.size();
|
||||
|
||||
if ( n == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
out << "Section Headers:" << std::endl;
|
||||
if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit
|
||||
out << "[ Nr ] Type Addr Size ES Flg Lk Inf Al Name" << std::endl;
|
||||
}
|
||||
else { // Output for 64-bit
|
||||
out << "[ Nr ] Type Addr Size ES Flg" << std::endl
|
||||
<< " Lk Inf Al Name" << std::endl;
|
||||
}
|
||||
|
||||
for ( Elf_Half i = 0; i < n; ++i ) { // For all sections
|
||||
section* sec = reader.sections[i];
|
||||
section_header( out, i, sec, reader.get_class() );
|
||||
}
|
||||
|
||||
out << "Key to Flags: W (write), A (alloc), X (execute)\n\n"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
section_header( std::ostream& out, Elf_Half no, const section* sec,
|
||||
unsigned char elf_class )
|
||||
{
|
||||
std::ios_base::fmtflags original_flags = out.flags();
|
||||
|
||||
if ( elf_class == ELFCLASS32 ) { // Output for 32-bit
|
||||
out << "["
|
||||
<< DUMP_DEC_FORMAT( 5 ) << no
|
||||
<< "] "
|
||||
<< DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() ) << " "
|
||||
<< DUMP_HEX_FORMAT( 8 ) << sec->get_address() << " "
|
||||
<< DUMP_HEX_FORMAT( 8 ) << sec->get_size() << " "
|
||||
<< DUMP_HEX_FORMAT( 2 ) << sec->get_entry_size() << " "
|
||||
<< DUMP_STR_FORMAT( 3 ) << section_flags( sec->get_flags() ) << " "
|
||||
<< DUMP_HEX_FORMAT( 2 ) << sec->get_link() << " "
|
||||
<< DUMP_HEX_FORMAT( 3 ) << sec->get_info() << " "
|
||||
<< DUMP_HEX_FORMAT( 2 ) << sec->get_addr_align() << " "
|
||||
<< DUMP_STR_FORMAT( 17 ) << sec->get_name() << " "
|
||||
<< std::endl;
|
||||
}
|
||||
else { // Output for 64-bit
|
||||
out << "["
|
||||
<< DUMP_DEC_FORMAT( 5 ) << no
|
||||
<< "] "
|
||||
<< DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() ) << " "
|
||||
<< DUMP_HEX_FORMAT( 16 ) << sec->get_address() << " "
|
||||
<< DUMP_HEX_FORMAT( 16 ) << sec->get_size() << " "
|
||||
<< DUMP_HEX_FORMAT( 4 ) << sec->get_entry_size() << " "
|
||||
<< DUMP_STR_FORMAT( 3 ) << section_flags( sec->get_flags() ) << " "
|
||||
<< std::endl
|
||||
<< " "
|
||||
<< DUMP_HEX_FORMAT( 4 ) << sec->get_link() << " "
|
||||
<< DUMP_HEX_FORMAT( 4 ) << sec->get_info() << " "
|
||||
<< DUMP_HEX_FORMAT( 4 ) << sec->get_addr_align() << " "
|
||||
<< DUMP_STR_FORMAT( 17 ) << sec->get_name() << " "
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
out.flags(original_flags);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
segment_headers( std::ostream& out, const elfio& reader )
|
||||
{
|
||||
Elf_Half n = reader.segments.size();
|
||||
if ( n == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
out << "Segment headers:" << std::endl;
|
||||
if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit
|
||||
out << "[ Nr ] Type VirtAddr PhysAddr FileSize Mem.Size Flags Align"
|
||||
<< std::endl;
|
||||
}
|
||||
else { // Output for 64-bit
|
||||
out << "[ Nr ] Type VirtAddr PhysAddr Flags" << std::endl
|
||||
<< " FileSize Mem.Size Align"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
for ( Elf_Half i = 0; i < n; ++i ) {
|
||||
segment* seg = reader.segments[i];
|
||||
segment_header( out, i, seg, reader.get_class() );
|
||||
}
|
||||
|
||||
out << std::endl;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
segment_header( std::ostream& out, Elf_Half no, const segment* seg,
|
||||
unsigned int elf_class )
|
||||
{
|
||||
std::ios_base::fmtflags original_flags = out.flags();
|
||||
|
||||
if ( elf_class == ELFCLASS32 ) { // Output for 32-bit
|
||||
out << "["
|
||||
<< DUMP_DEC_FORMAT( 5 ) << no
|
||||
<< "] "
|
||||
<< DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() ) << " "
|
||||
<< DUMP_HEX_FORMAT( 8 ) << seg->get_virtual_address() << " "
|
||||
<< DUMP_HEX_FORMAT( 8 ) << seg->get_physical_address() << " "
|
||||
<< DUMP_HEX_FORMAT( 8 ) << seg->get_file_size() << " "
|
||||
<< DUMP_HEX_FORMAT( 8 ) << seg->get_memory_size() << " "
|
||||
<< DUMP_STR_FORMAT( 8 ) << str_segment_flag( seg->get_flags() ) << " "
|
||||
<< DUMP_HEX_FORMAT( 8 ) << seg->get_align() << " "
|
||||
<< std::endl;
|
||||
}
|
||||
else { // Output for 64-bit
|
||||
out << "["
|
||||
<< DUMP_DEC_FORMAT( 5 ) << no
|
||||
<< "] "
|
||||
<< DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() ) << " "
|
||||
<< DUMP_HEX_FORMAT( 16 ) << seg->get_virtual_address() << " "
|
||||
<< DUMP_HEX_FORMAT( 16 ) << seg->get_physical_address() << " "
|
||||
<< DUMP_STR_FORMAT( 16 ) << str_segment_flag( seg->get_flags() ) << " "
|
||||
<< std::endl
|
||||
<< " "
|
||||
<< DUMP_HEX_FORMAT( 16 ) << seg->get_file_size() << " "
|
||||
<< DUMP_HEX_FORMAT( 16 ) << seg->get_memory_size() << " "
|
||||
<< DUMP_HEX_FORMAT( 16 ) << seg->get_align() << " "
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
out.flags(original_flags);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
symbol_tables( std::ostream& out, const elfio& reader )
|
||||
{
|
||||
Elf_Half n = reader.sections.size();
|
||||
for ( Elf_Half i = 0; i < n; ++i ) { // For all sections
|
||||
section* sec = reader.sections[i];
|
||||
if ( SHT_SYMTAB == sec->get_type() || SHT_DYNSYM == sec->get_type() ) {
|
||||
symbol_section_accessor symbols( reader, sec );
|
||||
|
||||
Elf_Xword sym_no = symbols.get_symbols_num();
|
||||
if ( sym_no > 0 ) {
|
||||
out << "Symbol table (" << sec->get_name() << ")" << std::endl;
|
||||
if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit
|
||||
out << "[ Nr ] Value Size Type Bind Sect Name"
|
||||
<< std::endl;
|
||||
}
|
||||
else { // Output for 64-bit
|
||||
out << "[ Nr ] Value Size Type Bind Sect" << std::endl
|
||||
<< " Name"
|
||||
<< std::endl;
|
||||
}
|
||||
for ( Elf_Xword i = 0; i < sym_no; ++i ) {
|
||||
std::string name;
|
||||
Elf64_Addr value = 0;
|
||||
Elf_Xword size = 0;
|
||||
unsigned char bind = 0;
|
||||
unsigned char type = 0;
|
||||
Elf_Half section = 0;
|
||||
unsigned char other = 0;
|
||||
symbols.get_symbol( i, name, value, size, bind, type, section, other );
|
||||
symbol_table( out, i, name, value, size, bind, type, section, reader.get_class() );
|
||||
}
|
||||
|
||||
out << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
symbol_table( std::ostream& out,
|
||||
Elf_Half no,
|
||||
std::string& name,
|
||||
Elf64_Addr value,
|
||||
Elf_Xword size,
|
||||
unsigned char bind,
|
||||
unsigned char type,
|
||||
Elf_Half section,
|
||||
unsigned int elf_class )
|
||||
{
|
||||
std::ios_base::fmtflags original_flags = out.flags();
|
||||
|
||||
if ( elf_class == ELFCLASS32 ) { // Output for 32-bit
|
||||
out << "["
|
||||
<< DUMP_DEC_FORMAT( 5 ) << no
|
||||
<< "] "
|
||||
<< DUMP_HEX_FORMAT( 8 ) << value << " "
|
||||
<< DUMP_HEX_FORMAT( 8 ) << size << " "
|
||||
<< DUMP_STR_FORMAT( 7 ) << str_symbol_type( type ) << " "
|
||||
<< DUMP_STR_FORMAT( 8 ) << str_symbol_bind( bind ) << " "
|
||||
<< DUMP_DEC_FORMAT( 5 ) << section << " "
|
||||
<< DUMP_STR_FORMAT( 1 ) << name << " "
|
||||
<< std::endl;
|
||||
}
|
||||
else { // Output for 64-bit
|
||||
out << "["
|
||||
<< DUMP_DEC_FORMAT( 5 ) << no
|
||||
<< "] "
|
||||
<< DUMP_HEX_FORMAT( 16 ) << value << " "
|
||||
<< DUMP_HEX_FORMAT( 16 ) << size << " "
|
||||
<< DUMP_STR_FORMAT( 7 ) << str_symbol_type( type ) << " "
|
||||
<< DUMP_STR_FORMAT( 8 ) << str_symbol_bind( bind ) << " "
|
||||
<< DUMP_DEC_FORMAT( 5 ) << section << " "
|
||||
<< std::endl
|
||||
<< " "
|
||||
<< DUMP_STR_FORMAT( 1 ) << name << " "
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
out.flags(original_flags);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
notes( std::ostream& out, const elfio& reader )
|
||||
{
|
||||
Elf_Half no = reader.sections.size();
|
||||
for ( Elf_Half i = 0; i < no; ++i ) { // For all sections
|
||||
section* sec = reader.sections[i];
|
||||
if ( SHT_NOTE == sec->get_type() ) { // Look at notes
|
||||
note_section_accessor notes( reader, sec );
|
||||
int no_notes = notes.get_notes_num();
|
||||
if ( no > 0 ) {
|
||||
out << "Note section (" << sec->get_name() << ")" << std::endl
|
||||
<< " No Type Name"
|
||||
<< std::endl;
|
||||
for ( Elf_Word j = 0; j < no_notes; ++j ) { // For all notes
|
||||
Elf_Word type;
|
||||
std::string name;
|
||||
void* desc;
|
||||
Elf_Word descsz;
|
||||
|
||||
if ( notes.get_note( j, type, name, desc, descsz ) ) {
|
||||
// 'name' usually contains \0 at the end. Try to fix it
|
||||
name = name.c_str();
|
||||
note( out, j, type, name );
|
||||
}
|
||||
}
|
||||
|
||||
out << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
note( std::ostream& out,
|
||||
int no,
|
||||
Elf_Word type,
|
||||
const std::string& name )
|
||||
{
|
||||
out << " ["
|
||||
<< DUMP_DEC_FORMAT( 2 ) << no
|
||||
<< "] "
|
||||
<< DUMP_HEX_FORMAT( 8 ) << type << " "
|
||||
<< DUMP_STR_FORMAT( 1 ) << name
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
dynamic_tags( std::ostream& out, const elfio& reader )
|
||||
{
|
||||
Elf_Half n = reader.sections.size();
|
||||
for ( Elf_Half i = 0; i < n; ++i ) { // For all sections
|
||||
section* sec = reader.sections[i];
|
||||
if ( SHT_DYNAMIC == sec->get_type() ) {
|
||||
dynamic_section_accessor dynamic( reader, sec );
|
||||
|
||||
Elf_Xword dyn_no = dynamic.get_entries_num();
|
||||
if ( dyn_no > 0 ) {
|
||||
out << "Dynamic section (" << sec->get_name() << ")" << std::endl;
|
||||
out << "[ Nr ] Tag Name/Value" << std::endl;
|
||||
for ( Elf_Xword i = 0; i < dyn_no; ++i ) {
|
||||
Elf_Xword tag = 0;
|
||||
Elf_Xword value = 0;
|
||||
std::string str;
|
||||
dynamic.get_entry( i, tag, value, str );
|
||||
dynamic_tag( out, i, tag, value, str, reader.get_class() );
|
||||
if ( DT_NULL == tag ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
dynamic_tag( std::ostream& out,
|
||||
Elf_Xword no,
|
||||
Elf_Xword tag,
|
||||
Elf_Xword value,
|
||||
std::string str,
|
||||
unsigned int /*elf_class*/ )
|
||||
{
|
||||
out << "["
|
||||
<< DUMP_DEC_FORMAT( 5 ) << no
|
||||
<< "] "
|
||||
<< DUMP_STR_FORMAT( 16 ) << str_dynamic_tag( tag ) << " ";
|
||||
if ( str.empty() ) {
|
||||
out << DUMP_HEX_FORMAT( 16 ) << value << " ";
|
||||
}
|
||||
else {
|
||||
out << DUMP_STR_FORMAT( 32 ) << str << " ";
|
||||
}
|
||||
out << std::endl;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
section_data( std::ostream& out, const section* sec )
|
||||
{
|
||||
std::ios_base::fmtflags original_flags = out.flags();
|
||||
|
||||
out << sec->get_name() << std::endl;
|
||||
const char* pdata = sec->get_data();
|
||||
if ( pdata ){
|
||||
ELFIO::Elf_Xword i;
|
||||
for ( i = 0; i < std::min( sec->get_size(), MAX_DATA_ENTRIES ); ++i ) {
|
||||
if ( i % 16 == 0 ) {
|
||||
out << "[" << DUMP_HEX_FORMAT( 8 ) << i << "]";
|
||||
}
|
||||
|
||||
out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF );
|
||||
|
||||
if ( i % 16 == 15 ) {
|
||||
out << std::endl;
|
||||
}
|
||||
}
|
||||
if ( i % 16 != 0 ) {
|
||||
out << std::endl;
|
||||
}
|
||||
|
||||
out.flags(original_flags);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
section_datas( std::ostream& out, const elfio& reader )
|
||||
{
|
||||
Elf_Half n = reader.sections.size();
|
||||
|
||||
if ( n == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
out << "Section Data:" << std::endl;
|
||||
|
||||
for ( Elf_Half i = 1; i < n; ++i ) { // For all sections
|
||||
section* sec = reader.sections[i];
|
||||
if ( sec->get_type() == SHT_NOBITS ) {
|
||||
continue;
|
||||
}
|
||||
section_data( out, sec );
|
||||
}
|
||||
|
||||
out << std::endl;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
segment_data( std::ostream& out, Elf_Half no, const segment* seg )
|
||||
{
|
||||
std::ios_base::fmtflags original_flags = out.flags();
|
||||
|
||||
out << "Segment # " << no << std::endl;
|
||||
const char* pdata = seg->get_data();
|
||||
if ( pdata ) {
|
||||
ELFIO::Elf_Xword i;
|
||||
for ( i = 0; i < std::min( seg->get_file_size(), MAX_DATA_ENTRIES ); ++i ) {
|
||||
if ( i % 16 == 0 ) {
|
||||
out << "[" << DUMP_HEX_FORMAT( 8 ) << i << "]";
|
||||
}
|
||||
|
||||
out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF );
|
||||
|
||||
if ( i % 16 == 15 ) {
|
||||
out << std::endl;
|
||||
}
|
||||
}
|
||||
if ( i % 16 != 0 ) {
|
||||
out << std::endl;
|
||||
}
|
||||
|
||||
out.flags(original_flags);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
segment_datas( std::ostream& out, const elfio& reader )
|
||||
{
|
||||
Elf_Half n = reader.segments.size();
|
||||
|
||||
if ( n == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
out << "Segment Data:" << std::endl;
|
||||
|
||||
for ( Elf_Half i = 0; i < n; ++i ) { // For all sections
|
||||
segment* seg = reader.segments[i];
|
||||
segment_data( out, i, seg );
|
||||
}
|
||||
|
||||
out << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
//------------------------------------------------------------------------------
|
||||
template< typename T, typename K >
|
||||
std::string
|
||||
static
|
||||
find_value_in_table( const T& table, const K& key )
|
||||
{
|
||||
std::string res = "?";
|
||||
for ( unsigned int i = 0; i < sizeof( table )/sizeof( table[0] ); ++i ) {
|
||||
if ( table[i].key == key ) {
|
||||
res = table[i].str;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< typename T, typename K >
|
||||
static
|
||||
std::string
|
||||
format_assoc( const T& table, const K& key )
|
||||
{
|
||||
std::string str = find_value_in_table( table, key );
|
||||
if ( str == "?" ) {
|
||||
std::ostringstream oss;
|
||||
oss << str << " (0x" << std::hex << key << ")";
|
||||
str = oss.str();
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< typename T >
|
||||
static
|
||||
std::string
|
||||
format_assoc( const T& table, const char key )
|
||||
{
|
||||
return format_assoc( table, (const int)key );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static
|
||||
std::string
|
||||
section_flags( Elf_Xword flags )
|
||||
{
|
||||
std::string ret = "";
|
||||
if ( flags & SHF_WRITE ) {
|
||||
ret += "W";
|
||||
}
|
||||
if ( flags & SHF_ALLOC ) {
|
||||
ret += "A";
|
||||
}
|
||||
if ( flags & SHF_EXECINSTR ) {
|
||||
ret += "X";
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#define STR_FUNC_TABLE( name ) \
|
||||
template< typename T > \
|
||||
static \
|
||||
std::string \
|
||||
str_##name( const T key ) \
|
||||
{ \
|
||||
return format_assoc( name##_table, key ); \
|
||||
}
|
||||
|
||||
STR_FUNC_TABLE( class )
|
||||
STR_FUNC_TABLE( endian )
|
||||
STR_FUNC_TABLE( version )
|
||||
STR_FUNC_TABLE( type )
|
||||
STR_FUNC_TABLE( machine )
|
||||
STR_FUNC_TABLE( section_type )
|
||||
STR_FUNC_TABLE( segment_type )
|
||||
STR_FUNC_TABLE( segment_flag )
|
||||
STR_FUNC_TABLE( symbol_bind )
|
||||
STR_FUNC_TABLE( symbol_type )
|
||||
STR_FUNC_TABLE( dynamic_tag )
|
||||
|
||||
#undef STR_FUNC_TABLE
|
||||
#undef DUMP_DEC_FORMAT
|
||||
#undef DUMP_HEX_FORMAT
|
||||
#undef DUMP_STR_FORMAT
|
||||
}; // class dump
|
||||
|
||||
|
||||
} // namespace ELFIO
|
||||
} // namespace amd
|
||||
|
||||
#endif // ELFIO_DUMP_HPP
|
||||
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
Copyright (C) 2001-2015 by Serge Lamikhov-Center
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef ELFIO_DYNAMIC_HPP
|
||||
#define ELFIO_DYNAMIC_HPP
|
||||
|
||||
namespace amd {
|
||||
namespace ELFIO {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class S >
|
||||
class dynamic_section_accessor_template
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
dynamic_section_accessor_template( const elfio& elf_file_, S* section_ ) :
|
||||
elf_file( elf_file_ ),
|
||||
dynamic_section( section_ )
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Xword
|
||||
get_entries_num() const
|
||||
{
|
||||
Elf_Xword nRet = 0;
|
||||
|
||||
if ( 0 != dynamic_section->get_entry_size() ) {
|
||||
nRet = dynamic_section->get_size() / dynamic_section->get_entry_size();
|
||||
}
|
||||
|
||||
return nRet;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool
|
||||
get_entry( Elf_Xword index,
|
||||
Elf_Xword& tag,
|
||||
Elf_Xword& value,
|
||||
std::string& str ) const
|
||||
{
|
||||
if ( index >= get_entries_num() ) { // Is index valid
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( elf_file.get_class() == ELFCLASS32 ) {
|
||||
generic_get_entry_dyn< Elf32_Dyn >( index, tag, value );
|
||||
}
|
||||
else {
|
||||
generic_get_entry_dyn< Elf64_Dyn >( index, tag, value );
|
||||
}
|
||||
|
||||
// If the tag may have a string table reference, prepare the string
|
||||
if ( tag == DT_NEEDED ||
|
||||
tag == DT_SONAME ||
|
||||
tag == DT_RPATH ||
|
||||
tag == DT_RUNPATH ) {
|
||||
string_section_accessor strsec =
|
||||
elf_file.sections[ get_string_table_index() ];
|
||||
const char* result = strsec.get_string( value );
|
||||
if ( 0 == result ) {
|
||||
str.clear();
|
||||
return false;
|
||||
}
|
||||
str = result;
|
||||
}
|
||||
else {
|
||||
str.clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
add_entry( Elf_Xword tag,
|
||||
Elf_Xword value )
|
||||
{
|
||||
if ( elf_file.get_class() == ELFCLASS32 ) {
|
||||
generic_add_entry< Elf32_Dyn >( tag, value );
|
||||
}
|
||||
else {
|
||||
generic_add_entry< Elf64_Dyn >( tag, value );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
add_entry( Elf_Xword tag,
|
||||
const std::string& str )
|
||||
{
|
||||
string_section_accessor strsec =
|
||||
elf_file.sections[ get_string_table_index() ];
|
||||
Elf_Xword value = strsec.add_string( str );
|
||||
add_entry( tag, value );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Half
|
||||
get_string_table_index() const
|
||||
{
|
||||
return (Elf_Half)dynamic_section->get_link();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class T >
|
||||
void
|
||||
generic_get_entry_dyn( Elf_Xword index,
|
||||
Elf_Xword& tag,
|
||||
Elf_Xword& value ) const
|
||||
{
|
||||
const endianess_convertor& convertor = elf_file.get_convertor();
|
||||
|
||||
// Check unusual case when dynamic section has no data
|
||||
if( dynamic_section->get_data() == 0 ||
|
||||
( index + 1 ) * dynamic_section->get_entry_size() > dynamic_section->get_size() ) {
|
||||
tag = DT_NULL;
|
||||
value = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const T* pEntry = reinterpret_cast<const T*>(
|
||||
dynamic_section->get_data() +
|
||||
index * dynamic_section->get_entry_size() );
|
||||
tag = convertor( pEntry->d_tag );
|
||||
switch ( tag ) {
|
||||
case DT_NULL:
|
||||
case DT_SYMBOLIC:
|
||||
case DT_TEXTREL:
|
||||
case DT_BIND_NOW:
|
||||
value = 0;
|
||||
break;
|
||||
case DT_NEEDED:
|
||||
case DT_PLTRELSZ:
|
||||
case DT_RELASZ:
|
||||
case DT_RELAENT:
|
||||
case DT_STRSZ:
|
||||
case DT_SYMENT:
|
||||
case DT_SONAME:
|
||||
case DT_RPATH:
|
||||
case DT_RELSZ:
|
||||
case DT_RELENT:
|
||||
case DT_PLTREL:
|
||||
case DT_INIT_ARRAYSZ:
|
||||
case DT_FINI_ARRAYSZ:
|
||||
case DT_RUNPATH:
|
||||
case DT_FLAGS:
|
||||
case DT_PREINIT_ARRAYSZ:
|
||||
value = convertor( pEntry->d_un.d_val );
|
||||
break;
|
||||
case DT_PLTGOT:
|
||||
case DT_HASH:
|
||||
case DT_STRTAB:
|
||||
case DT_SYMTAB:
|
||||
case DT_RELA:
|
||||
case DT_INIT:
|
||||
case DT_FINI:
|
||||
case DT_REL:
|
||||
case DT_DEBUG:
|
||||
case DT_JMPREL:
|
||||
case DT_INIT_ARRAY:
|
||||
case DT_FINI_ARRAY:
|
||||
case DT_PREINIT_ARRAY:
|
||||
default:
|
||||
value = convertor( pEntry->d_un.d_ptr );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class T >
|
||||
void
|
||||
generic_add_entry( Elf_Xword tag, Elf_Xword value )
|
||||
{
|
||||
const endianess_convertor& convertor = elf_file.get_convertor();
|
||||
|
||||
T entry;
|
||||
|
||||
switch ( tag ) {
|
||||
case DT_NULL:
|
||||
case DT_SYMBOLIC:
|
||||
case DT_TEXTREL:
|
||||
case DT_BIND_NOW:
|
||||
value = 0;
|
||||
case DT_NEEDED:
|
||||
case DT_PLTRELSZ:
|
||||
case DT_RELASZ:
|
||||
case DT_RELAENT:
|
||||
case DT_STRSZ:
|
||||
case DT_SYMENT:
|
||||
case DT_SONAME:
|
||||
case DT_RPATH:
|
||||
case DT_RELSZ:
|
||||
case DT_RELENT:
|
||||
case DT_PLTREL:
|
||||
case DT_INIT_ARRAYSZ:
|
||||
case DT_FINI_ARRAYSZ:
|
||||
case DT_RUNPATH:
|
||||
case DT_FLAGS:
|
||||
case DT_PREINIT_ARRAYSZ:
|
||||
entry.d_un.d_val = convertor( value );
|
||||
break;
|
||||
case DT_PLTGOT:
|
||||
case DT_HASH:
|
||||
case DT_STRTAB:
|
||||
case DT_SYMTAB:
|
||||
case DT_RELA:
|
||||
case DT_INIT:
|
||||
case DT_FINI:
|
||||
case DT_REL:
|
||||
case DT_DEBUG:
|
||||
case DT_JMPREL:
|
||||
case DT_INIT_ARRAY:
|
||||
case DT_FINI_ARRAY:
|
||||
case DT_PREINIT_ARRAY:
|
||||
default:
|
||||
entry.d_un.d_ptr = convertor( value );
|
||||
break;
|
||||
}
|
||||
|
||||
entry.d_tag = convertor( tag );
|
||||
|
||||
dynamic_section->append_data( reinterpret_cast<char*>( &entry ), sizeof( entry ) );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
const elfio& elf_file;
|
||||
S* dynamic_section;
|
||||
};
|
||||
|
||||
using dynamic_section_accessor = dynamic_section_accessor_template<section>;
|
||||
using const_dynamic_section_accessor = dynamic_section_accessor_template<const section>;
|
||||
|
||||
} // namespace ELFIO
|
||||
} // namespace amd
|
||||
|
||||
#endif // ELFIO_DYNAMIC_HPP
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
Copyright (C) 2001-2015 by Serge Lamikhov-Center
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef ELF_HEADER_HPP
|
||||
#define ELF_HEADER_HPP
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace amd {
|
||||
namespace ELFIO {
|
||||
|
||||
class elf_header
|
||||
{
|
||||
public:
|
||||
virtual ~elf_header() {};
|
||||
virtual bool load( std::istream& stream ) = 0;
|
||||
virtual bool save( std::ostream& stream ) const = 0;
|
||||
|
||||
// ELF header functions
|
||||
ELFIO_GET_ACCESS_DECL( unsigned char, class );
|
||||
ELFIO_GET_ACCESS_DECL( unsigned char, elf_version );
|
||||
ELFIO_GET_ACCESS_DECL( unsigned char, encoding );
|
||||
ELFIO_GET_ACCESS_DECL( Elf_Half, header_size );
|
||||
ELFIO_GET_ACCESS_DECL( Elf_Half, section_entry_size );
|
||||
ELFIO_GET_ACCESS_DECL( Elf_Half, segment_entry_size );
|
||||
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, version );
|
||||
ELFIO_GET_SET_ACCESS_DECL( unsigned char, os_abi );
|
||||
ELFIO_GET_SET_ACCESS_DECL( unsigned char, abi_version );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Half, type );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Half, machine );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, entry );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Half, sections_num );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, sections_offset );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Half, segments_num );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, segments_offset );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Half, section_name_str_index );
|
||||
};
|
||||
|
||||
|
||||
template< class T > struct elf_header_impl_types;
|
||||
template<> struct elf_header_impl_types<Elf32_Ehdr> {
|
||||
typedef Elf32_Phdr Phdr_type;
|
||||
typedef Elf32_Shdr Shdr_type;
|
||||
static const unsigned char file_class = ELFCLASS32;
|
||||
};
|
||||
template<> struct elf_header_impl_types<Elf64_Ehdr> {
|
||||
typedef Elf64_Phdr Phdr_type;
|
||||
typedef Elf64_Shdr Shdr_type;
|
||||
static const unsigned char file_class = ELFCLASS64;
|
||||
};
|
||||
|
||||
template< class T > class elf_header_impl : public elf_header
|
||||
{
|
||||
public:
|
||||
elf_header_impl( endianess_convertor* convertor_,
|
||||
unsigned char encoding )
|
||||
{
|
||||
convertor = convertor_;
|
||||
|
||||
std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), '\0' );
|
||||
|
||||
header.e_ident[EI_MAG0] = ELFMAG0;
|
||||
header.e_ident[EI_MAG1] = ELFMAG1;
|
||||
header.e_ident[EI_MAG2] = ELFMAG2;
|
||||
header.e_ident[EI_MAG3] = ELFMAG3;
|
||||
header.e_ident[EI_CLASS] = elf_header_impl_types<T>::file_class;
|
||||
header.e_ident[EI_DATA] = encoding;
|
||||
header.e_ident[EI_VERSION] = EV_CURRENT;
|
||||
header.e_version = (*convertor)( (Elf_Word)EV_CURRENT );
|
||||
header.e_ehsize = ( sizeof( header ) );
|
||||
header.e_ehsize = (*convertor)( header.e_ehsize );
|
||||
header.e_shstrndx = (*convertor)( (Elf_Half)1 );
|
||||
header.e_phentsize = sizeof( typename elf_header_impl_types<T>::Phdr_type );
|
||||
header.e_shentsize = sizeof( typename elf_header_impl_types<T>::Shdr_type );
|
||||
header.e_phentsize = (*convertor)( header.e_phentsize );
|
||||
header.e_shentsize = (*convertor)( header.e_shentsize );
|
||||
}
|
||||
|
||||
bool
|
||||
load( std::istream& stream )
|
||||
{
|
||||
stream.seekg( 0 );
|
||||
stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) );
|
||||
|
||||
return (stream.gcount() == sizeof( header ) );
|
||||
}
|
||||
|
||||
bool
|
||||
save( std::ostream& stream ) const
|
||||
{
|
||||
stream.seekp( 0 );
|
||||
stream.write( reinterpret_cast<const char*>( &header ), sizeof( header ) );
|
||||
|
||||
return stream.good();
|
||||
}
|
||||
|
||||
// ELF header functions
|
||||
ELFIO_GET_ACCESS( unsigned char, class, header.e_ident[EI_CLASS] );
|
||||
ELFIO_GET_ACCESS( unsigned char, elf_version, header.e_ident[EI_VERSION] );
|
||||
ELFIO_GET_ACCESS( unsigned char, encoding, header.e_ident[EI_DATA] );
|
||||
ELFIO_GET_ACCESS( Elf_Half, header_size, header.e_ehsize );
|
||||
ELFIO_GET_ACCESS( Elf_Half, section_entry_size, header.e_shentsize );
|
||||
ELFIO_GET_ACCESS( Elf_Half, segment_entry_size, header.e_phentsize );
|
||||
|
||||
ELFIO_GET_SET_ACCESS( Elf_Word, version, header.e_version);
|
||||
ELFIO_GET_SET_ACCESS( unsigned char, os_abi, header.e_ident[EI_OSABI] );
|
||||
ELFIO_GET_SET_ACCESS( unsigned char, abi_version, header.e_ident[EI_ABIVERSION] );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Half, type, header.e_type );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Half, machine, header.e_machine );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Word, flags, header.e_flags );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Half, section_name_str_index, header.e_shstrndx );
|
||||
ELFIO_GET_SET_ACCESS( Elf64_Addr, entry, header.e_entry );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Half, sections_num, header.e_shnum );
|
||||
ELFIO_GET_SET_ACCESS( Elf64_Off, sections_offset, header.e_shoff );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Half, segments_num, header.e_phnum );
|
||||
ELFIO_GET_SET_ACCESS( Elf64_Off, segments_offset, header.e_phoff );
|
||||
|
||||
private:
|
||||
T header;
|
||||
endianess_convertor* convertor;
|
||||
};
|
||||
|
||||
} // namespace ELFIO
|
||||
} // namespace amd
|
||||
|
||||
#endif // ELF_HEADER_HPP
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
Copyright (C) 2001-2015 by Serge Lamikhov-Center
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef ELFIO_NOTE_HPP
|
||||
#define ELFIO_NOTE_HPP
|
||||
|
||||
namespace amd {
|
||||
namespace ELFIO {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// There are discrepancies in documentations. SCO documentation
|
||||
// (http://www.sco.com/developers/gabi/latest/ch5.pheader.html#note_section)
|
||||
// requires 8 byte entries alignment for 64-bit ELF file,
|
||||
// but Oracle's definition uses the same structure
|
||||
// for 32-bit and 64-bit formats.
|
||||
// (https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-18048.html)
|
||||
//
|
||||
// It looks like EM_X86_64 Linux implementation is similar to Oracle's
|
||||
// definition. Therefore, the same alignment works for both formats
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class S >
|
||||
class note_section_accessor_template
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
note_section_accessor_template( const elfio& elf_file_, S* section_ ) :
|
||||
elf_file( elf_file_ ), note_section( section_ )
|
||||
{
|
||||
process_section();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Word
|
||||
get_notes_num() const
|
||||
{
|
||||
return (Elf_Word)note_start_positions.size();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool
|
||||
get_note( Elf_Word index,
|
||||
Elf_Word& type,
|
||||
std::string& name,
|
||||
void*& desc,
|
||||
Elf_Word& descSize ) const
|
||||
{
|
||||
if ( index >= note_section->get_size() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* pData = note_section->get_data() + note_start_positions[index];
|
||||
int align = sizeof( Elf_Word );
|
||||
|
||||
const endianess_convertor& convertor = elf_file.get_convertor();
|
||||
type = convertor( *(const Elf_Word*)( pData + 2*align ) );
|
||||
Elf_Word namesz = convertor( *(const Elf_Word*)( pData ) );
|
||||
descSize = convertor( *(const Elf_Word*)( pData + sizeof( namesz ) ) );
|
||||
Elf_Xword max_name_size = note_section->get_size() - note_start_positions[index];
|
||||
if ( namesz < 1 ||
|
||||
namesz > max_name_size ||
|
||||
namesz + descSize > max_name_size ) {
|
||||
return false;
|
||||
}
|
||||
name.assign( pData + 3*align, namesz - 1);
|
||||
if ( 0 == descSize ) {
|
||||
desc = 0;
|
||||
}
|
||||
else {
|
||||
desc = const_cast<char*> ( pData + 3*align +
|
||||
( ( namesz + align - 1 )/align )*align );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void add_note( Elf_Word type,
|
||||
const std::string& name,
|
||||
const void* desc,
|
||||
Elf_Word descSize )
|
||||
{
|
||||
const endianess_convertor& convertor = elf_file.get_convertor();
|
||||
|
||||
int align = sizeof( Elf_Word );
|
||||
Elf_Word nameLen = (Elf_Word)name.size() + 1;
|
||||
Elf_Word nameLenConv = convertor( nameLen );
|
||||
std::string buffer( reinterpret_cast<char*>( &nameLenConv ), align );
|
||||
Elf_Word descSizeConv = convertor( descSize );
|
||||
buffer.append( reinterpret_cast<char*>( &descSizeConv ), align );
|
||||
type = convertor( type );
|
||||
buffer.append( reinterpret_cast<char*>( &type ), align );
|
||||
buffer.append( name );
|
||||
buffer.append( 1, '\x00' );
|
||||
const char pad[] = { '\0', '\0', '\0', '\0' };
|
||||
if ( nameLen % align != 0 ) {
|
||||
buffer.append( pad, align - nameLen % align );
|
||||
}
|
||||
if ( desc != 0 && descSize != 0 ) {
|
||||
buffer.append( reinterpret_cast<const char*>( desc ), descSize );
|
||||
if ( descSize % align != 0 ) {
|
||||
buffer.append( pad, align - descSize % align );
|
||||
}
|
||||
}
|
||||
|
||||
note_start_positions.push_back( note_section->get_size() );
|
||||
note_section->append_data( buffer );
|
||||
}
|
||||
|
||||
private:
|
||||
//------------------------------------------------------------------------------
|
||||
void process_section()
|
||||
{
|
||||
const endianess_convertor& convertor = elf_file.get_convertor();
|
||||
const char* data = note_section->get_data();
|
||||
Elf_Xword size = note_section->get_size();
|
||||
Elf_Xword current = 0;
|
||||
|
||||
note_start_positions.clear();
|
||||
|
||||
// Is it empty?
|
||||
if ( 0 == data || 0 == size ) {
|
||||
return;
|
||||
}
|
||||
|
||||
int align = sizeof( Elf_Word );
|
||||
while ( current + 3*align <= size ) {
|
||||
note_start_positions.push_back( current );
|
||||
Elf_Word namesz = convertor(
|
||||
*(const Elf_Word*)( data + current ) );
|
||||
Elf_Word descsz = convertor(
|
||||
*(const Elf_Word*)( data + current + sizeof( namesz ) ) );
|
||||
|
||||
current += 3*sizeof( Elf_Word ) +
|
||||
( ( namesz + align - 1 ) / align ) * align +
|
||||
( ( descsz + align - 1 ) / align ) * align;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
const elfio& elf_file;
|
||||
S* note_section;
|
||||
std::vector<Elf_Xword> note_start_positions;
|
||||
};
|
||||
|
||||
using note_section_accessor = note_section_accessor_template<section>;
|
||||
using const_note_section_accessor = note_section_accessor_template<const section>;
|
||||
|
||||
} // namespace ELFIO
|
||||
} // namespace amd
|
||||
|
||||
#endif // ELFIO_NOTE_HPP
|
||||
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
Copyright (C) 2001-2015 by Serge Lamikhov-Center
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef ELFIO_RELOCATION_HPP
|
||||
#define ELFIO_RELOCATION_HPP
|
||||
|
||||
namespace amd {
|
||||
namespace ELFIO {
|
||||
|
||||
template<typename T> struct get_sym_and_type;
|
||||
template<> struct get_sym_and_type< Elf32_Rel >
|
||||
{
|
||||
static int get_r_sym( Elf_Xword info )
|
||||
{
|
||||
return ELF32_R_SYM( (Elf_Word)info );
|
||||
}
|
||||
static int get_r_type( Elf_Xword info )
|
||||
{
|
||||
return ELF32_R_TYPE( (Elf_Word)info );
|
||||
}
|
||||
};
|
||||
template<> struct get_sym_and_type< Elf32_Rela >
|
||||
{
|
||||
static int get_r_sym( Elf_Xword info )
|
||||
{
|
||||
return ELF32_R_SYM( (Elf_Word)info );
|
||||
}
|
||||
static int get_r_type( Elf_Xword info )
|
||||
{
|
||||
return ELF32_R_TYPE( (Elf_Word)info );
|
||||
}
|
||||
};
|
||||
template<> struct get_sym_and_type< Elf64_Rel >
|
||||
{
|
||||
static int get_r_sym( Elf_Xword info )
|
||||
{
|
||||
return ELF64_R_SYM( info );
|
||||
}
|
||||
static int get_r_type( Elf_Xword info )
|
||||
{
|
||||
return ELF64_R_TYPE( info );
|
||||
}
|
||||
};
|
||||
template<> struct get_sym_and_type< Elf64_Rela >
|
||||
{
|
||||
static int get_r_sym( Elf_Xword info )
|
||||
{
|
||||
return ELF64_R_SYM( info );
|
||||
}
|
||||
static int get_r_type( Elf_Xword info )
|
||||
{
|
||||
return ELF64_R_TYPE( info );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class S >
|
||||
class relocation_section_accessor_template
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
relocation_section_accessor_template( const elfio& elf_file_, S* section_ ) :
|
||||
elf_file( elf_file_ ),
|
||||
relocation_section( section_ )
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Xword
|
||||
get_entries_num() const
|
||||
{
|
||||
Elf_Xword nRet = 0;
|
||||
|
||||
if ( 0 != relocation_section->get_entry_size() ) {
|
||||
nRet = relocation_section->get_size() / relocation_section->get_entry_size();
|
||||
}
|
||||
|
||||
return nRet;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool
|
||||
get_entry( Elf_Xword index,
|
||||
Elf64_Addr& offset,
|
||||
Elf_Word& symbol,
|
||||
Elf_Word& type,
|
||||
Elf_Sxword& addend ) const
|
||||
{
|
||||
if ( index >= get_entries_num() ) { // Is index valid
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( elf_file.get_class() == ELFCLASS32 ) {
|
||||
if ( SHT_REL == relocation_section->get_type() ) {
|
||||
generic_get_entry_rel< Elf32_Rel >( index, offset, symbol,
|
||||
type, addend );
|
||||
}
|
||||
else if ( SHT_RELA == relocation_section->get_type() ) {
|
||||
generic_get_entry_rela< Elf32_Rela >( index, offset, symbol,
|
||||
type, addend );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( SHT_REL == relocation_section->get_type() ) {
|
||||
generic_get_entry_rel< Elf64_Rel >( index, offset, symbol,
|
||||
type, addend );
|
||||
}
|
||||
else if ( SHT_RELA == relocation_section->get_type() ) {
|
||||
generic_get_entry_rela< Elf64_Rela >( index, offset, symbol,
|
||||
type, addend );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool
|
||||
get_entry( Elf_Xword index,
|
||||
Elf64_Addr& offset,
|
||||
Elf64_Addr& symbolValue,
|
||||
std::string& symbolName,
|
||||
Elf_Word& type,
|
||||
Elf_Sxword& addend,
|
||||
Elf_Sxword& calcValue ) const
|
||||
{
|
||||
// Do regular job
|
||||
Elf_Word symbol;
|
||||
bool ret = get_entry( index, offset, symbol, type, addend );
|
||||
|
||||
// Find the symbol
|
||||
Elf_Xword size;
|
||||
unsigned char bind;
|
||||
unsigned char symbolType;
|
||||
Elf_Half section;
|
||||
unsigned char other;
|
||||
|
||||
symbol_section_accessor symbols( elf_file, elf_file.sections[get_symbol_table_index()] );
|
||||
ret = ret && symbols.get_symbol( symbol, symbolName, symbolValue,
|
||||
size, bind, symbolType, section, other );
|
||||
|
||||
if ( ret ) { // Was it successful?
|
||||
switch ( type ) {
|
||||
case R_386_NONE: // none
|
||||
calcValue = 0;
|
||||
break;
|
||||
case R_386_32: // S + A
|
||||
calcValue = symbolValue + addend;
|
||||
break;
|
||||
case R_386_PC32: // S + A - P
|
||||
calcValue = symbolValue + addend - offset;
|
||||
break;
|
||||
case R_386_GOT32: // G + A - P
|
||||
calcValue = 0;
|
||||
break;
|
||||
case R_386_PLT32: // L + A - P
|
||||
calcValue = 0;
|
||||
break;
|
||||
case R_386_COPY: // none
|
||||
calcValue = 0;
|
||||
break;
|
||||
case R_386_GLOB_DAT: // S
|
||||
case R_386_JMP_SLOT: // S
|
||||
calcValue = symbolValue;
|
||||
break;
|
||||
case R_386_RELATIVE: // B + A
|
||||
calcValue = addend;
|
||||
break;
|
||||
case R_386_GOTOFF: // S + A - GOT
|
||||
calcValue = 0;
|
||||
break;
|
||||
case R_386_GOTPC: // GOT + A - P
|
||||
calcValue = 0;
|
||||
break;
|
||||
default: // Not recognized symbol!
|
||||
calcValue = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
add_entry( Elf64_Addr offset, Elf_Xword info )
|
||||
{
|
||||
if ( elf_file.get_class() == ELFCLASS32 ) {
|
||||
generic_add_entry< Elf32_Rel >( offset, info );
|
||||
}
|
||||
else {
|
||||
generic_add_entry< Elf64_Rel >( offset, info );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned char type )
|
||||
{
|
||||
Elf_Xword info;
|
||||
if ( elf_file.get_class() == ELFCLASS32 ) {
|
||||
info = ELF32_R_INFO( (Elf_Xword)symbol, type );
|
||||
}
|
||||
else {
|
||||
info = ELF64_R_INFO((Elf_Xword)symbol, type );
|
||||
}
|
||||
|
||||
add_entry( offset, info );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend )
|
||||
{
|
||||
if ( elf_file.get_class() == ELFCLASS32 ) {
|
||||
generic_add_entry< Elf32_Rela >( offset, info, addend );
|
||||
}
|
||||
else {
|
||||
generic_add_entry< Elf64_Rela >( offset, info, addend );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned char type,
|
||||
Elf_Sxword addend )
|
||||
{
|
||||
Elf_Xword info;
|
||||
if ( elf_file.get_class() == ELFCLASS32 ) {
|
||||
info = ELF32_R_INFO( (Elf_Xword)symbol, type );
|
||||
}
|
||||
else {
|
||||
info = ELF64_R_INFO( (Elf_Xword)symbol, type );
|
||||
}
|
||||
|
||||
add_entry( offset, info, addend );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
add_entry( string_section_accessor str_writer,
|
||||
const char* str,
|
||||
symbol_section_accessor sym_writer,
|
||||
Elf64_Addr value,
|
||||
Elf_Word size,
|
||||
unsigned char sym_info,
|
||||
unsigned char other,
|
||||
Elf_Half shndx,
|
||||
Elf64_Addr offset,
|
||||
unsigned char type )
|
||||
{
|
||||
Elf_Word str_index = str_writer.add_string( str );
|
||||
Elf_Word sym_index = sym_writer.add_symbol( str_index, value, size,
|
||||
sym_info, other, shndx );
|
||||
add_entry( offset, sym_index, type );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Half
|
||||
get_symbol_table_index() const
|
||||
{
|
||||
return (Elf_Half)relocation_section->get_link();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class T >
|
||||
void
|
||||
generic_get_entry_rel( Elf_Xword index,
|
||||
Elf64_Addr& offset,
|
||||
Elf_Word& symbol,
|
||||
Elf_Word& type,
|
||||
Elf_Sxword& addend ) const
|
||||
{
|
||||
const endianess_convertor& convertor = elf_file.get_convertor();
|
||||
|
||||
const T* pEntry = reinterpret_cast<const T*>(
|
||||
relocation_section->get_data() +
|
||||
index * relocation_section->get_entry_size() );
|
||||
offset = convertor( pEntry->r_offset );
|
||||
Elf_Xword tmp = convertor( pEntry->r_info );
|
||||
symbol = get_sym_and_type<T>::get_r_sym( tmp );
|
||||
type = get_sym_and_type<T>::get_r_type( tmp );
|
||||
addend = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class T >
|
||||
void
|
||||
generic_get_entry_rela( Elf_Xword index,
|
||||
Elf64_Addr& offset,
|
||||
Elf_Word& symbol,
|
||||
Elf_Word& type,
|
||||
Elf_Sxword& addend ) const
|
||||
{
|
||||
const endianess_convertor& convertor = elf_file.get_convertor();
|
||||
|
||||
const T* pEntry = reinterpret_cast<const T*>(
|
||||
relocation_section->get_data() +
|
||||
index * relocation_section->get_entry_size() );
|
||||
offset = convertor( pEntry->r_offset );
|
||||
Elf_Xword tmp = convertor( pEntry->r_info );
|
||||
symbol = get_sym_and_type<T>::get_r_sym( tmp );
|
||||
type = get_sym_and_type<T>::get_r_type( tmp );
|
||||
addend = convertor( pEntry->r_addend );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class T >
|
||||
void
|
||||
generic_add_entry( Elf64_Addr offset, Elf_Xword info )
|
||||
{
|
||||
const endianess_convertor& convertor = elf_file.get_convertor();
|
||||
|
||||
T entry;
|
||||
entry.r_offset = offset;
|
||||
entry.r_info = info;
|
||||
entry.r_offset = convertor( entry.r_offset );
|
||||
entry.r_info = convertor( entry.r_info );
|
||||
|
||||
relocation_section->append_data( reinterpret_cast<char*>( &entry ), sizeof( entry ) );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class T >
|
||||
void
|
||||
generic_add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend )
|
||||
{
|
||||
const endianess_convertor& convertor = elf_file.get_convertor();
|
||||
|
||||
T entry;
|
||||
entry.r_offset = offset;
|
||||
entry.r_info = info;
|
||||
entry.r_addend = addend;
|
||||
entry.r_offset = convertor( entry.r_offset );
|
||||
entry.r_info = convertor( entry.r_info );
|
||||
entry.r_addend = convertor( entry.r_addend );
|
||||
|
||||
relocation_section->append_data( reinterpret_cast<char*>( &entry ), sizeof( entry ) );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
const elfio& elf_file;
|
||||
S* relocation_section;
|
||||
};
|
||||
|
||||
using relocation_section_accessor = relocation_section_accessor_template<section>;
|
||||
using const_relocation_section_accessor = relocation_section_accessor_template<const section>;
|
||||
|
||||
} // namespace ELFIO
|
||||
} // namespace amd
|
||||
|
||||
#endif // ELFIO_RELOCATION_HPP
|
||||
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
Copyright (C) 2001-2015 by Serge Lamikhov-Center
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef ELFIO_SECTION_HPP
|
||||
#define ELFIO_SECTION_HPP
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
namespace amd {
|
||||
namespace ELFIO {
|
||||
|
||||
class section
|
||||
{
|
||||
friend class elfio;
|
||||
public:
|
||||
virtual ~section() {};
|
||||
|
||||
ELFIO_GET_ACCESS_DECL ( Elf_Half, index );
|
||||
ELFIO_GET_SET_ACCESS_DECL( std::string, name );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, flags );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, info );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, link );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, addr_align );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, entry_size );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, address );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, size );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, name_string_offset );
|
||||
ELFIO_GET_ACCESS_DECL ( Elf64_Off, offset );
|
||||
|
||||
virtual const char* get_data() const = 0;
|
||||
virtual void set_data( const char* pData, Elf_Word size ) = 0;
|
||||
virtual void set_data( const std::string& data ) = 0;
|
||||
virtual void append_data( const char* pData, Elf_Word size ) = 0;
|
||||
virtual void append_data( const std::string& data ) = 0;
|
||||
virtual size_t get_stream_size() const = 0;
|
||||
virtual void set_stream_size( size_t value ) = 0;
|
||||
|
||||
protected:
|
||||
ELFIO_SET_ACCESS_DECL( Elf64_Off, offset );
|
||||
ELFIO_SET_ACCESS_DECL( Elf_Half, index );
|
||||
|
||||
virtual void load( std::istream& stream,
|
||||
std::streampos header_offset ) = 0;
|
||||
virtual void save( std::ostream& stream,
|
||||
std::streampos header_offset,
|
||||
std::streampos data_offset ) = 0;
|
||||
virtual bool is_address_initialized() const = 0;
|
||||
};
|
||||
|
||||
|
||||
template< class T >
|
||||
class section_impl : public section
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
section_impl( const endianess_convertor* convertor_ ) : convertor( convertor_ )
|
||||
{
|
||||
std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), '\0' );
|
||||
is_address_set = false;
|
||||
data = 0;
|
||||
data_size = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
~section_impl()
|
||||
{
|
||||
delete [] data;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Section info functions
|
||||
ELFIO_GET_SET_ACCESS( Elf_Word, type, header.sh_type );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Xword, flags, header.sh_flags );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Xword, size, header.sh_size );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Word, link, header.sh_link );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Word, info, header.sh_info );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Xword, addr_align, header.sh_addralign );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Xword, entry_size, header.sh_entsize );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Word, name_string_offset, header.sh_name );
|
||||
ELFIO_GET_ACCESS ( Elf64_Addr, address, header.sh_addr );
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Half
|
||||
get_index() const
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
std::string
|
||||
get_name() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
set_name( std::string name_ )
|
||||
{
|
||||
name = name_;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
set_address( Elf64_Addr value )
|
||||
{
|
||||
header.sh_addr = value;
|
||||
header.sh_addr = (*convertor)( header.sh_addr );
|
||||
is_address_set = true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool
|
||||
is_address_initialized() const
|
||||
{
|
||||
return is_address_set;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const char*
|
||||
get_data() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
set_data( const char* raw_data, Elf_Word size )
|
||||
{
|
||||
if ( get_type() != SHT_NOBITS ) {
|
||||
delete [] data;
|
||||
try {
|
||||
data = new char[size];
|
||||
} catch (const std::bad_alloc&) {
|
||||
data = 0;
|
||||
data_size = 0;
|
||||
size = 0;
|
||||
}
|
||||
if ( 0 != data && 0 != raw_data ) {
|
||||
data_size = size;
|
||||
std::copy( raw_data, raw_data + size, data );
|
||||
}
|
||||
}
|
||||
|
||||
set_size( size );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
set_data( const std::string& str_data )
|
||||
{
|
||||
return set_data( str_data.c_str(), (Elf_Word)str_data.size() );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
append_data( const char* raw_data, Elf_Word size )
|
||||
{
|
||||
if ( get_type() != SHT_NOBITS ) {
|
||||
if ( get_size() + size < data_size ) {
|
||||
std::copy( raw_data, raw_data + size, data + get_size() );
|
||||
}
|
||||
else {
|
||||
data_size = 2*( data_size + size);
|
||||
char* new_data;
|
||||
try {
|
||||
new_data = new char[data_size];
|
||||
} catch (const std::bad_alloc&) {
|
||||
new_data = 0;
|
||||
size = 0;
|
||||
}
|
||||
if ( 0 != new_data ) {
|
||||
std::copy( data, data + get_size(), new_data );
|
||||
std::copy( raw_data, raw_data + size, new_data + get_size() );
|
||||
delete [] data;
|
||||
data = new_data;
|
||||
}
|
||||
}
|
||||
set_size( get_size() + size );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
append_data( const std::string& str_data )
|
||||
{
|
||||
return append_data( str_data.c_str(), (Elf_Word)str_data.size() );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
protected:
|
||||
//------------------------------------------------------------------------------
|
||||
ELFIO_GET_SET_ACCESS( Elf64_Off, offset, header.sh_offset );
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
set_index( Elf_Half value )
|
||||
{
|
||||
index = value;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
load( std::istream& stream,
|
||||
std::streampos header_offset )
|
||||
{
|
||||
std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), '\0' );
|
||||
|
||||
stream.seekg ( 0, stream.end );
|
||||
set_stream_size ( stream.tellg() );
|
||||
|
||||
stream.seekg( header_offset );
|
||||
stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) );
|
||||
|
||||
|
||||
Elf_Xword size = get_size();
|
||||
if ( 0 == data && SHT_NULL != get_type() && SHT_NOBITS != get_type() && size < get_stream_size()) {
|
||||
try {
|
||||
data = new char[size + 1];
|
||||
} catch (const std::bad_alloc&) {
|
||||
data = 0;
|
||||
data_size = 0;
|
||||
}
|
||||
|
||||
if ( ( 0 != size ) && ( 0 != data ) ) {
|
||||
stream.seekg( (*convertor)( header.sh_offset ) );
|
||||
stream.read( data, size );
|
||||
data[size] = 0; // Ensure data is ended with 0 to avoid oob read
|
||||
data_size = size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
save( std::ostream& stream,
|
||||
std::streampos header_offset,
|
||||
std::streampos data_offset )
|
||||
{
|
||||
if ( 0 != get_index() ) {
|
||||
header.sh_offset = data_offset;
|
||||
header.sh_offset = (*convertor)( header.sh_offset );
|
||||
}
|
||||
|
||||
save_header( stream, header_offset );
|
||||
if ( get_type() != SHT_NOBITS && get_type() != SHT_NULL &&
|
||||
get_size() != 0 && data != 0 ) {
|
||||
save_data( stream, data_offset );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
save_header( std::ostream& stream,
|
||||
std::streampos header_offset ) const
|
||||
{
|
||||
stream.seekp( header_offset );
|
||||
stream.write( reinterpret_cast<const char*>( &header ), sizeof( header ) );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
save_data( std::ostream& stream,
|
||||
std::streampos data_offset ) const
|
||||
{
|
||||
stream.seekp( data_offset );
|
||||
stream.write( get_data(), get_size() );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
size_t get_stream_size() const
|
||||
{
|
||||
return stream_size;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void set_stream_size(size_t value)
|
||||
{
|
||||
stream_size = value;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
T header;
|
||||
Elf_Half index;
|
||||
std::string name;
|
||||
char* data;
|
||||
Elf_Word data_size;
|
||||
const endianess_convertor* convertor;
|
||||
bool is_address_set;
|
||||
size_t stream_size;
|
||||
};
|
||||
|
||||
} // namespace ELFIO
|
||||
} // namespace amd
|
||||
|
||||
#endif // ELFIO_SECTION_HPP
|
||||
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
Copyright (C) 2001-2015 by Serge Lamikhov-Center
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef ELFIO_SEGMENT_HPP
|
||||
#define ELFIO_SEGMENT_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
namespace amd {
|
||||
namespace ELFIO {
|
||||
|
||||
class segment
|
||||
{
|
||||
friend class elfio;
|
||||
public:
|
||||
virtual ~segment() {};
|
||||
|
||||
ELFIO_GET_ACCESS_DECL ( Elf_Half, index );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, align );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, virtual_address );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, physical_address );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, file_size );
|
||||
ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, memory_size );
|
||||
ELFIO_GET_ACCESS_DECL( Elf64_Off, offset );
|
||||
|
||||
virtual const char* get_data() const = 0;
|
||||
|
||||
virtual Elf_Half add_section_index( Elf_Half index, Elf_Xword addr_align ) = 0;
|
||||
virtual Elf_Half get_sections_num() const = 0;
|
||||
virtual Elf_Half get_section_index_at( Elf_Half num ) const = 0;
|
||||
virtual bool is_offset_initialized() const = 0;
|
||||
|
||||
protected:
|
||||
ELFIO_SET_ACCESS_DECL( Elf64_Off, offset );
|
||||
ELFIO_SET_ACCESS_DECL( Elf_Half, index );
|
||||
|
||||
virtual const std::vector<Elf_Half>& get_sections() const = 0;
|
||||
virtual void load( std::istream& stream, std::streampos header_offset ) = 0;
|
||||
virtual void save( std::ostream& stream, std::streampos header_offset,
|
||||
std::streampos data_offset ) = 0;
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class T >
|
||||
class segment_impl : public segment
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
segment_impl( endianess_convertor* convertor_ ) :
|
||||
stream_size( 0 ), index( 0 ), data( 0 ), convertor( convertor_ )
|
||||
{
|
||||
is_offset_set = false;
|
||||
std::fill_n( reinterpret_cast<char*>( &ph ), sizeof( ph ), '\0' );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
virtual ~segment_impl()
|
||||
{
|
||||
delete [] data;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Section info functions
|
||||
ELFIO_GET_SET_ACCESS( Elf_Word, type, ph.p_type );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Word, flags, ph.p_flags );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Xword, align, ph.p_align );
|
||||
ELFIO_GET_SET_ACCESS( Elf64_Addr, virtual_address, ph.p_vaddr );
|
||||
ELFIO_GET_SET_ACCESS( Elf64_Addr, physical_address, ph.p_paddr );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Xword, file_size, ph.p_filesz );
|
||||
ELFIO_GET_SET_ACCESS( Elf_Xword, memory_size, ph.p_memsz );
|
||||
ELFIO_GET_ACCESS( Elf64_Off, offset, ph.p_offset );
|
||||
size_t stream_size;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
size_t
|
||||
get_stream_size() const
|
||||
{
|
||||
return stream_size;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
set_stream_size(size_t value)
|
||||
{
|
||||
stream_size = value;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Half
|
||||
get_index() const
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const char*
|
||||
get_data() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Half
|
||||
add_section_index( Elf_Half sec_index, Elf_Xword addr_align )
|
||||
{
|
||||
sections.push_back( sec_index );
|
||||
if ( addr_align > get_align() ) {
|
||||
set_align( addr_align );
|
||||
}
|
||||
|
||||
return (Elf_Half)sections.size();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Half
|
||||
get_sections_num() const
|
||||
{
|
||||
return (Elf_Half)sections.size();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Half
|
||||
get_section_index_at( Elf_Half num ) const
|
||||
{
|
||||
if ( num < sections.size() ) {
|
||||
return sections[num];
|
||||
}
|
||||
|
||||
return Elf_Half(-1);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
protected:
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
set_offset( Elf64_Off value )
|
||||
{
|
||||
ph.p_offset = value;
|
||||
ph.p_offset = (*convertor)( ph.p_offset );
|
||||
is_offset_set = true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool
|
||||
is_offset_initialized() const
|
||||
{
|
||||
return is_offset_set;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const std::vector<Elf_Half>&
|
||||
get_sections() const
|
||||
{
|
||||
return sections;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
set_index( Elf_Half value )
|
||||
{
|
||||
index = value;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
load( std::istream& stream,
|
||||
std::streampos header_offset )
|
||||
{
|
||||
|
||||
stream.seekg ( 0, stream.end );
|
||||
set_stream_size ( stream.tellg() );
|
||||
|
||||
stream.seekg( header_offset );
|
||||
stream.read( reinterpret_cast<char*>( &ph ), sizeof( ph ) );
|
||||
is_offset_set = true;
|
||||
|
||||
if ( PT_NULL != get_type() && 0 != get_file_size() ) {
|
||||
stream.seekg( (*convertor)( ph.p_offset ) );
|
||||
Elf_Xword size = get_file_size();
|
||||
|
||||
if ( size > get_stream_size() ) {
|
||||
data = 0;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
data = new char[size + 1];
|
||||
} catch (const std::bad_alloc&) {
|
||||
data = 0;
|
||||
}
|
||||
|
||||
if ( 0 != data ) {
|
||||
stream.read( data, size );
|
||||
data[size] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void save( std::ostream& stream,
|
||||
std::streampos header_offset,
|
||||
std::streampos data_offset )
|
||||
{
|
||||
ph.p_offset = data_offset;
|
||||
ph.p_offset = (*convertor)(ph.p_offset);
|
||||
stream.seekp( header_offset );
|
||||
stream.write( reinterpret_cast<const char*>( &ph ), sizeof( ph ) );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
T ph;
|
||||
Elf_Half index;
|
||||
char* data;
|
||||
std::vector<Elf_Half> sections;
|
||||
endianess_convertor* convertor;
|
||||
bool is_offset_set;
|
||||
};
|
||||
|
||||
} // namespace ELFIO
|
||||
} // namespace amd
|
||||
|
||||
#endif // ELFIO_SEGMENT_HPP
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
Copyright (C) 2001-2015 by Serge Lamikhov-Center
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef ELFIO_STRINGS_HPP
|
||||
#define ELFIO_STRINGS_HPP
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
namespace amd {
|
||||
namespace ELFIO {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class S >
|
||||
class string_section_accessor_template
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
string_section_accessor_template( S* section_ ) :
|
||||
string_section( section_ )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const char*
|
||||
get_string( Elf_Word index ) const
|
||||
{
|
||||
if ( string_section ) {
|
||||
if ( index < string_section->get_size() ) {
|
||||
const char* data = string_section->get_data();
|
||||
if ( 0 != data ) {
|
||||
return data + index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Word
|
||||
add_string( const char* str )
|
||||
{
|
||||
Elf_Word current_position = 0;
|
||||
|
||||
if (string_section) {
|
||||
// Strings are addeded to the end of the current section data
|
||||
current_position = (Elf_Word)string_section->get_size();
|
||||
|
||||
if ( current_position == 0 ) {
|
||||
char empty_string = '\0';
|
||||
string_section->append_data( &empty_string, 1 );
|
||||
current_position++;
|
||||
}
|
||||
string_section->append_data( str, (Elf_Word)std::strlen( str ) + 1 );
|
||||
}
|
||||
|
||||
return current_position;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Word
|
||||
add_string( const std::string& str )
|
||||
{
|
||||
return add_string( str.c_str() );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
S* string_section;
|
||||
};
|
||||
|
||||
using string_section_accessor = string_section_accessor_template<section>;
|
||||
using const_string_section_accessor = string_section_accessor_template<const section>;
|
||||
|
||||
} // namespace ELFIO
|
||||
} // namespace amd
|
||||
|
||||
#endif // ELFIO_STRINGS_HPP
|
||||
@@ -0,0 +1,413 @@
|
||||
/*
|
||||
Copyright (C) 2001-2015 by Serge Lamikhov-Center
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef ELFIO_SYMBOLS_HPP
|
||||
#define ELFIO_SYMBOLS_HPP
|
||||
|
||||
namespace amd {
|
||||
namespace ELFIO {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class S >
|
||||
class symbol_section_accessor_template
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
symbol_section_accessor_template( const elfio& elf_file_, S* symbol_section_ ) :
|
||||
elf_file( elf_file_ ),
|
||||
symbol_section( symbol_section_ )
|
||||
{
|
||||
find_hash_section();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Xword
|
||||
get_symbols_num() const
|
||||
{
|
||||
Elf_Xword nRet = 0;
|
||||
if ( 0 != symbol_section->get_entry_size() ) {
|
||||
nRet = symbol_section->get_size() / symbol_section->get_entry_size();
|
||||
}
|
||||
|
||||
return nRet;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool
|
||||
get_symbol( Elf_Xword index,
|
||||
std::string& name,
|
||||
Elf64_Addr& value,
|
||||
Elf_Xword& size,
|
||||
unsigned char& bind,
|
||||
unsigned char& type,
|
||||
Elf_Half& section_index,
|
||||
unsigned char& other ) const
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if ( elf_file.get_class() == ELFCLASS32 ) {
|
||||
ret = generic_get_symbol<Elf32_Sym>( index, name, value, size, bind,
|
||||
type, section_index, other );
|
||||
}
|
||||
else {
|
||||
ret = generic_get_symbol<Elf64_Sym>( index, name, value, size, bind,
|
||||
type, section_index, other );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/* Search in terms of symbol name */
|
||||
bool
|
||||
get_symbol( const std::string& name,
|
||||
Elf64_Addr& value,
|
||||
Elf_Xword& size,
|
||||
unsigned char& bind,
|
||||
unsigned char& type,
|
||||
Elf_Half& section_index,
|
||||
unsigned char& other ) const
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if ( 0 != get_hash_table_index() ) {
|
||||
Elf_Word nbucket = *(const Elf_Word*)hash_section->get_data();
|
||||
Elf_Word nchain = *(const Elf_Word*)( hash_section->get_data() +
|
||||
sizeof( Elf_Word ) );
|
||||
Elf_Word val = elf_hash( (const unsigned char*)name.c_str() );
|
||||
Elf_Word y = *(const Elf_Word*)( hash_section->get_data() +
|
||||
( 2 + val % nbucket ) * sizeof( Elf_Word ) );
|
||||
std::string str;
|
||||
get_symbol( y, str, value, size, bind, type, section_index, other );
|
||||
while ( str != name && STN_UNDEF != y && y < nchain ) {
|
||||
y = *(const Elf_Word*)( hash_section->get_data() +
|
||||
( 2 + nbucket + y ) * sizeof( Elf_Word ) );
|
||||
get_symbol( y, str, value, size, bind, type, section_index, other );
|
||||
}
|
||||
if ( str == name ) {
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( Elf_Xword i = 0; i < get_symbols_num() && !ret; i++ ) {
|
||||
std::string symbol_name;
|
||||
if ( get_symbol( i, symbol_name, value, size, bind, type,
|
||||
section_index, other) ) {
|
||||
if ( symbol_name == name ) {
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
/* Search in terms of symbol name and section name */
|
||||
bool
|
||||
get_symbol( const std::string& name,
|
||||
const std::string& section_name,
|
||||
Elf64_Addr& value,
|
||||
Elf_Xword& size,
|
||||
unsigned char& bind,
|
||||
unsigned char& type,
|
||||
Elf_Half& section_index,
|
||||
unsigned char& other ) const
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if ( 0 != get_hash_table_index() ) {
|
||||
Elf_Word nbucket = *(const Elf_Word*)hash_section->get_data();
|
||||
Elf_Word nchain = *(const Elf_Word*)( hash_section->get_data() +
|
||||
sizeof( Elf_Word ) );
|
||||
Elf_Word val = elf_hash( (const unsigned char*)name.c_str() );
|
||||
Elf_Word y = *(const Elf_Word*)( hash_section->get_data() +
|
||||
( 2 + val % nbucket ) * sizeof( Elf_Word ) );
|
||||
std::string str;
|
||||
get_symbol( y, str, value, size, bind, type, section_index, other );
|
||||
while ( (str != name || section_name != elf_file.sections[section_index]->get_name() )
|
||||
&& STN_UNDEF != y && y < nchain ) {
|
||||
y = *(const Elf_Word*)( hash_section->get_data() +
|
||||
( 2 + nbucket + y ) * sizeof( Elf_Word ) );
|
||||
get_symbol( y, str, value, size, bind, type, section_index, other );
|
||||
}
|
||||
if ( str == name && section_name == elf_file.sections[section_index]->get_name() ) {
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( Elf_Xword i = 0; i < get_symbols_num() && !ret; i++ ) {
|
||||
std::string symbol_name;
|
||||
if ( get_symbol( i, symbol_name, value, size, bind, type,
|
||||
section_index, other) ) {
|
||||
if ( symbol_name == name &&
|
||||
section_name == elf_file.sections[section_index]->get_name() ) {
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/* Search in terms of value */
|
||||
bool
|
||||
get_symbol( const Elf64_Addr& value,
|
||||
std::string& name,
|
||||
Elf_Xword& size,
|
||||
unsigned char& bind,
|
||||
unsigned char& type,
|
||||
Elf_Half& section_index,
|
||||
unsigned char& other ) const
|
||||
{
|
||||
|
||||
|
||||
const endianess_convertor& convertor = elf_file.get_convertor();
|
||||
|
||||
Elf_Xword idx = 0;
|
||||
bool match = false;
|
||||
Elf64_Addr v = 0;
|
||||
|
||||
if ( elf_file.get_class() == ELFCLASS32 ) {
|
||||
match = generic_search_symbols<Elf32_Sym>([&convertor, &value](const Elf32_Sym* sym) {
|
||||
return convertor(sym->st_value) == value;
|
||||
}, idx);
|
||||
} else {
|
||||
match = generic_search_symbols<Elf64_Sym>([&convertor, &value](const Elf64_Sym* sym) {
|
||||
return convertor(sym->st_value) == value;
|
||||
}, idx);
|
||||
}
|
||||
|
||||
if ( match ) {
|
||||
return get_symbol( idx, name, v, size, bind, type, section_index, other );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Word
|
||||
add_symbol( Elf_Word name, Elf64_Addr value, Elf_Xword size,
|
||||
unsigned char info, unsigned char other,
|
||||
Elf_Half shndx )
|
||||
{
|
||||
Elf_Word nRet;
|
||||
|
||||
if ( symbol_section->get_size() == 0 ) {
|
||||
if ( elf_file.get_class() == ELFCLASS32 ) {
|
||||
nRet = generic_add_symbol<Elf32_Sym>( 0, 0, 0, 0, 0, 0 );
|
||||
}
|
||||
else {
|
||||
nRet = generic_add_symbol<Elf64_Sym>( 0, 0, 0, 0, 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( elf_file.get_class() == ELFCLASS32 ) {
|
||||
nRet = generic_add_symbol<Elf32_Sym>( name, value, size, info, other,
|
||||
shndx );
|
||||
}
|
||||
else {
|
||||
nRet = generic_add_symbol<Elf64_Sym>( name, value, size, info, other,
|
||||
shndx );
|
||||
}
|
||||
|
||||
return nRet;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Word
|
||||
add_symbol( Elf_Word name, Elf64_Addr value, Elf_Xword size,
|
||||
unsigned char bind, unsigned char type, unsigned char other,
|
||||
Elf_Half shndx )
|
||||
{
|
||||
return add_symbol( name, value, size, ELF_ST_INFO( bind, type ), other, shndx );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Word
|
||||
add_symbol( string_section_accessor& pStrWriter, const char* str,
|
||||
Elf64_Addr value, Elf_Xword size,
|
||||
unsigned char info, unsigned char other,
|
||||
Elf_Half shndx )
|
||||
{
|
||||
Elf_Word index = pStrWriter.add_string( str );
|
||||
return add_symbol( index, value, size, info, other, shndx );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Word
|
||||
add_symbol( string_section_accessor& pStrWriter, const char* str,
|
||||
Elf64_Addr value, Elf_Xword size,
|
||||
unsigned char bind, unsigned char type, unsigned char other,
|
||||
Elf_Half shndx )
|
||||
{
|
||||
return add_symbol( pStrWriter, str, value, size, ELF_ST_INFO( bind, type ), other, shndx );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
find_hash_section()
|
||||
{
|
||||
hash_section = 0;
|
||||
hash_section_index = 0;
|
||||
Elf_Half nSecNo = elf_file.sections.size();
|
||||
for ( Elf_Half i = 0; i < nSecNo && 0 == hash_section_index; ++i ) {
|
||||
const section* sec = elf_file.sections[i];
|
||||
if ( sec->get_link() == symbol_section->get_index() ) {
|
||||
hash_section = sec;
|
||||
hash_section_index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Half
|
||||
get_string_table_index() const
|
||||
{
|
||||
return (Elf_Half)symbol_section->get_link();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Half
|
||||
get_hash_table_index() const
|
||||
{
|
||||
return hash_section_index;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class T >
|
||||
const T*
|
||||
generic_get_symbol_ptr(Elf_Xword index) const {
|
||||
if ( 0 != symbol_section->get_data() && index < get_symbols_num() ) {
|
||||
const T* pSym = reinterpret_cast<const T*>(
|
||||
symbol_section->get_data() +
|
||||
index * symbol_section->get_entry_size() );
|
||||
|
||||
return pSym;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class T >
|
||||
bool
|
||||
generic_search_symbols(std::function<bool(const T*)> match, Elf_Xword& idx) const {
|
||||
for (Elf_Xword i = 0; i < get_symbols_num(); i++){
|
||||
const T* symPtr = generic_get_symbol_ptr<T>(i);
|
||||
|
||||
if (symPtr == nullptr)
|
||||
return false;
|
||||
|
||||
if (match(symPtr)) {
|
||||
idx = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class T >
|
||||
bool
|
||||
generic_get_symbol( Elf_Xword index,
|
||||
std::string& name, Elf64_Addr& value,
|
||||
Elf_Xword& size,
|
||||
unsigned char& bind, unsigned char& type,
|
||||
Elf_Half& section_index,
|
||||
unsigned char& other ) const
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if ( 0 != symbol_section->get_data() && index < get_symbols_num() ) {
|
||||
const T* pSym = reinterpret_cast<const T*>(
|
||||
symbol_section->get_data() +
|
||||
index * symbol_section->get_entry_size() );
|
||||
|
||||
const endianess_convertor& convertor = elf_file.get_convertor();
|
||||
|
||||
section* string_section = elf_file.sections[get_string_table_index()];
|
||||
string_section_accessor str_reader( string_section );
|
||||
const char* pStr = str_reader.get_string( convertor( pSym->st_name ) );
|
||||
if ( 0 != pStr ) {
|
||||
name = pStr;
|
||||
}
|
||||
value = convertor( pSym->st_value );
|
||||
size = convertor( pSym->st_size );
|
||||
bind = ELF_ST_BIND( pSym->st_info );
|
||||
type = ELF_ST_TYPE( pSym->st_info );
|
||||
section_index = convertor( pSym->st_shndx );
|
||||
other = pSym->st_other;
|
||||
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class T >
|
||||
Elf_Word
|
||||
generic_add_symbol( Elf_Word name, Elf64_Addr value, Elf_Xword size,
|
||||
unsigned char info, unsigned char other,
|
||||
Elf_Half shndx )
|
||||
{
|
||||
const endianess_convertor& convertor = elf_file.get_convertor();
|
||||
|
||||
T entry;
|
||||
entry.st_name = convertor( name );
|
||||
entry.st_value = value;
|
||||
entry.st_value = convertor( entry.st_value );
|
||||
entry.st_size = size;
|
||||
entry.st_size = convertor( entry.st_size );
|
||||
entry.st_info = convertor( info );
|
||||
entry.st_other = convertor( other );
|
||||
entry.st_shndx = convertor( shndx );
|
||||
|
||||
symbol_section->append_data( reinterpret_cast<char*>( &entry ),
|
||||
sizeof( entry ) );
|
||||
|
||||
Elf_Word nRet = symbol_section->get_size() / sizeof( entry ) - 1;
|
||||
|
||||
return nRet;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
const elfio& elf_file;
|
||||
S* symbol_section;
|
||||
Elf_Half hash_section_index;
|
||||
const section* hash_section;
|
||||
};
|
||||
|
||||
using symbol_section_accessor = symbol_section_accessor_template<section>;
|
||||
using const_symbol_section_accessor = symbol_section_accessor_template<const section>;
|
||||
|
||||
} // namespace ELFIO
|
||||
} // namespace amd
|
||||
|
||||
#endif // ELFIO_SYMBOLS_HPP
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
Copyright (C) 2001-2015 by Serge Lamikhov-Center
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef ELFIO_UTILS_HPP
|
||||
#define ELFIO_UTILS_HPP
|
||||
|
||||
#define ELFIO_GET_ACCESS( TYPE, NAME, FIELD ) \
|
||||
TYPE get_##NAME() const \
|
||||
{ \
|
||||
return (*convertor)( FIELD ); \
|
||||
}
|
||||
#define ELFIO_SET_ACCESS( TYPE, NAME, FIELD ) \
|
||||
void set_##NAME( TYPE value ) \
|
||||
{ \
|
||||
FIELD = value; \
|
||||
FIELD = (*convertor)( FIELD ); \
|
||||
}
|
||||
#define ELFIO_GET_SET_ACCESS( TYPE, NAME, FIELD ) \
|
||||
TYPE get_##NAME() const \
|
||||
{ \
|
||||
return (*convertor)( FIELD ); \
|
||||
} \
|
||||
void set_##NAME( TYPE value ) \
|
||||
{ \
|
||||
FIELD = value; \
|
||||
FIELD = (*convertor)( FIELD ); \
|
||||
}
|
||||
|
||||
#define ELFIO_GET_ACCESS_DECL( TYPE, NAME ) \
|
||||
virtual TYPE get_##NAME() const = 0
|
||||
|
||||
#define ELFIO_SET_ACCESS_DECL( TYPE, NAME ) \
|
||||
virtual void set_##NAME( TYPE value ) = 0
|
||||
|
||||
#define ELFIO_GET_SET_ACCESS_DECL( TYPE, NAME ) \
|
||||
virtual TYPE get_##NAME() const = 0; \
|
||||
virtual void set_##NAME( TYPE value ) = 0
|
||||
|
||||
namespace amd {
|
||||
namespace ELFIO {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class endianess_convertor {
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
endianess_convertor()
|
||||
{
|
||||
need_conversion = false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
setup( unsigned char elf_file_encoding )
|
||||
{
|
||||
need_conversion = ( elf_file_encoding != get_host_encoding() );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
uint64_t
|
||||
operator()( uint64_t value ) const
|
||||
{
|
||||
if ( !need_conversion ) {
|
||||
return value;
|
||||
}
|
||||
value =
|
||||
( ( value & 0x00000000000000FFull ) << 56 ) |
|
||||
( ( value & 0x000000000000FF00ull ) << 40 ) |
|
||||
( ( value & 0x0000000000FF0000ull ) << 24 ) |
|
||||
( ( value & 0x00000000FF000000ull ) << 8 ) |
|
||||
( ( value & 0x000000FF00000000ull ) >> 8 ) |
|
||||
( ( value & 0x0000FF0000000000ull ) >> 24 ) |
|
||||
( ( value & 0x00FF000000000000ull ) >> 40 ) |
|
||||
( ( value & 0xFF00000000000000ull ) >> 56 );
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int64_t
|
||||
operator()( int64_t value ) const
|
||||
{
|
||||
if ( !need_conversion ) {
|
||||
return value;
|
||||
}
|
||||
return (int64_t)(*this)( (uint64_t)value );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
uint32_t
|
||||
operator()( uint32_t value ) const
|
||||
{
|
||||
if ( !need_conversion ) {
|
||||
return value;
|
||||
}
|
||||
value =
|
||||
( ( value & 0x000000FF ) << 24 ) |
|
||||
( ( value & 0x0000FF00 ) << 8 ) |
|
||||
( ( value & 0x00FF0000 ) >> 8 ) |
|
||||
( ( value & 0xFF000000 ) >> 24 );
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int32_t
|
||||
operator()( int32_t value ) const
|
||||
{
|
||||
if ( !need_conversion ) {
|
||||
return value;
|
||||
}
|
||||
return (int32_t)(*this)( (uint32_t)value );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
uint16_t
|
||||
operator()( uint16_t value ) const
|
||||
{
|
||||
if ( !need_conversion ) {
|
||||
return value;
|
||||
}
|
||||
value =
|
||||
( ( value & 0x00FF ) << 8 ) |
|
||||
( ( value & 0xFF00 ) >> 8 );
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int16_t
|
||||
operator()( int16_t value ) const
|
||||
{
|
||||
if ( !need_conversion ) {
|
||||
return value;
|
||||
}
|
||||
return (int16_t)(*this)( (uint16_t)value );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int8_t
|
||||
operator()( int8_t value ) const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
uint8_t
|
||||
operator()( uint8_t value ) const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
//------------------------------------------------------------------------------
|
||||
unsigned char
|
||||
get_host_encoding() const
|
||||
{
|
||||
static const int tmp = 1;
|
||||
if ( 1 == *(const char*)&tmp ) {
|
||||
return ELFDATA2LSB;
|
||||
}
|
||||
else {
|
||||
return ELFDATA2MSB;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
bool need_conversion;
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline
|
||||
uint32_t
|
||||
elf_hash( const unsigned char *name )
|
||||
{
|
||||
uint32_t h = 0, g;
|
||||
while ( *name ) {
|
||||
h = (h << 4) + *name++;
|
||||
g = h & 0xf0000000;
|
||||
if ( g != 0 )
|
||||
h ^= g >> 24;
|
||||
h &= ~g;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
} // namespace ELFIO
|
||||
} // namespace amd
|
||||
|
||||
#endif // ELFIO_UTILS_HPP
|
||||
@@ -0,0 +1,46 @@
|
||||
#-------------------------------------elf_test--------------------------------------#
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
# This is unit test for amd::Elf.
|
||||
# The test is on top of rocclr, so rocclr must be built and installed firstly.
|
||||
# This file is seperate from cmake file of rocclr to prevent interference.
|
||||
|
||||
find_package(amd_comgr REQUIRED CONFIG
|
||||
PATHS
|
||||
/opt/rocm/
|
||||
PATH_SUFFIXES
|
||||
cmake/amd_comgr
|
||||
lib/cmake/amd_comgr)
|
||||
|
||||
find_package(hsa-runtime64 REQUIRED CONFIG
|
||||
PATHS
|
||||
/opt/rocm/
|
||||
PATH_SUFFIXES
|
||||
cmake/hsa-runtime64)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
# Look for ROCclr which contains elfio
|
||||
find_package(ROCclr REQUIRED CONFIG
|
||||
PATHS
|
||||
/opt/rocm
|
||||
/opt/rocm/rocclr)
|
||||
|
||||
add_executable(elf_test main.cpp)
|
||||
set_target_properties(
|
||||
elf_test PROPERTIES
|
||||
CXX_STANDARD 11
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS OFF
|
||||
RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
target_include_directories(elf_test
|
||||
PRIVATE
|
||||
$<TARGET_PROPERTY:amdrocclr_static,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||
|
||||
add_definitions(-DUSE_COMGR_LIBRARY -DCOMGR_DYN_DLL -DWITH_LIGHTNING_COMPILER -DDEBUG)
|
||||
|
||||
#target_link_libraries(elf_test PUBLIC pthread)
|
||||
#target_link_libraries(elf_test PRIVATE amdrocclr_static pthread hsa-runtime64::hsa-runtime64)
|
||||
target_link_libraries(elf_test PRIVATE amdrocclr_static)
|
||||
|
||||
#install(TARGETS elf_test RUNTIME DESTINATION bin)
|
||||
#-------------------------------------elf_test--------------------------------------#
|
||||
@@ -0,0 +1,21 @@
|
||||
1. To build release version
|
||||
In test folder,
|
||||
mkdir release (if release doesn't exist)
|
||||
cd release
|
||||
cmake ..
|
||||
make
|
||||
|
||||
|
||||
2. To build debug version
|
||||
In test folder,
|
||||
mkdir debug (if debug doesn't exist)
|
||||
cd debug
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug ..
|
||||
make
|
||||
|
||||
3. Run test
|
||||
rm -f *.bin
|
||||
./elf_test
|
||||
|
||||
To get debug log,
|
||||
AMD_LOG_LEVEL=5 ./elf_test
|
||||
@@ -0,0 +1,356 @@
|
||||
#include <elf/elf.hpp>
|
||||
#include <string>
|
||||
#include <utils/flags.hpp>
|
||||
#include <utils/debug.hpp>
|
||||
|
||||
using namespace amd::ELFIO;
|
||||
|
||||
static constexpr uint32_t target_ = 11;
|
||||
static constexpr char comment_[] = "comment text";
|
||||
static constexpr size_t commentSize_ = strlen(comment_) + 1;
|
||||
|
||||
// Elf::RODATA, ".rodata", 1, SHT_PROGBITS, SHF_ALLOC,
|
||||
static const amd::Elf::SymbolInfo rodataSymbolInfos_[] = {
|
||||
{ ".rodata", nullptr, 0, "data__fmetadata", "fmetatdata", strlen("fmetatdata") + 1 },
|
||||
{ ".rodata", nullptr, 0, "data__amdil", "amdildata", strlen("amdildata") + 1 },
|
||||
{ ".rodata", nullptr, 0, "data__metadata", "metadata", strlen("metadata") + 1 },
|
||||
{ ".rodata", nullptr, 0, "data__header", "header", strlen("header") + 1 },
|
||||
{ ".rodata", nullptr, 0, "data__global", "global", strlen("global") + 1 },
|
||||
{ ".rodata", nullptr, 0, "data__randome0", "xu\0e\0\0l", sizeof("xu\0e\0\0l") }, // binary
|
||||
{ ".rodata", nullptr, 0, "data__randome1", "\0j\0\0w\0", sizeof("\0j\0\0w\0") }, // binary
|
||||
};
|
||||
|
||||
static constexpr size_t rodataSymbolInfosSize_ = sizeof(rodataSymbolInfos_)
|
||||
/ sizeof(rodataSymbolInfos_[0]);
|
||||
|
||||
// Elf::COMMENT, ".comment", 1, SHT_PROGBITS, 0,
|
||||
static const amd::Elf::SymbolInfo commentSymbolInfos_[] = {
|
||||
{ ".comment", nullptr, 0, "compile", "-g -I/opt/include", strlen("-g -I/opt/include") + 1 },
|
||||
{ ".comment", nullptr, 0, "link", "-g -l/opt/rocm/lib", strlen("-g -l/opt/rocm/lib") + 1 },
|
||||
};
|
||||
static constexpr size_t commentSymbolInfosSize_ = sizeof(commentSymbolInfos_)
|
||||
/ sizeof(commentSymbolInfos_[0]);
|
||||
|
||||
struct NoteInfo {
|
||||
const char *noteName;
|
||||
const char *noteDesc;
|
||||
size_t descSize;
|
||||
};
|
||||
|
||||
static constexpr NoteInfo noteInfos_[] = {
|
||||
{ "notename0", "sjfasdfe2Afs", strlen("sjfasdfe2Afs") + 1 },
|
||||
{ "notename1", "AsdmvdfFfkd", strlen("AsdmvdfFfkd") + 1 },
|
||||
{ "notename2", "d\0kelH\0D", sizeof("d\0kelH\0D") }, // binary
|
||||
{ "notename3", "\0F\0kA\0", sizeof("\0F\0kA\0") }, // binary
|
||||
};
|
||||
|
||||
static const size_t noteInfosSize_ = sizeof(noteInfos_) / sizeof(noteInfos_[0]);
|
||||
|
||||
bool set(amd::Elf* elf) {
|
||||
if (!elf->setTarget(target_, amd::Elf::CPU_PLATFORM)) {
|
||||
LogError("elf->setTarget() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!elf->setType(ET_EXEC)) {
|
||||
LogError("elf->elf() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!elf->addSection(amd::Elf::COMMENT, comment_, commentSize_)) {
|
||||
LogError("elf->addSection() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
LogInfo("writing rodataSymbolInfo");
|
||||
|
||||
for (i = 0; i < rodataSymbolInfosSize_; i++) {
|
||||
auto& info = rodataSymbolInfos_[i];
|
||||
if (!elf->addSymbol(amd::Elf::RODATA, info.sym_name.c_str(),
|
||||
info.address, info.size)) {
|
||||
LogPrintfError("elf->addSymbol(RODATA) failed at index %zu", i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LogInfo("Succeeded");
|
||||
LogInfo("writing commentSymbolInfo");
|
||||
|
||||
for (i = 0; i < commentSymbolInfosSize_; i++) {
|
||||
auto& info = commentSymbolInfos_[i];
|
||||
if (!elf->addSymbol(amd::Elf::COMMENT, info.sym_name.c_str(),
|
||||
info.address, info.size)) {
|
||||
LogPrintfError("elf->addSymbol(COMMENT) failed at index %zu", i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LogInfo("Succeeded");
|
||||
LogInfo("writing noteInfos");
|
||||
|
||||
for (i = 0; i < noteInfosSize_; i++) {
|
||||
auto& info = noteInfos_[i];
|
||||
if (!elf->addNote(info.noteName, info.noteDesc, info.descSize)) {
|
||||
LogPrintfError("elf->addNote() failed at index %zu", i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LogInfo("Succeeded");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool verify(amd::Elf* elf) {
|
||||
uint16_t machine = amd::Elf::OCL_TARGETS_LAST;
|
||||
amd::Elf::ElfPlatform platform = amd::Elf::LAST_PLATFORM;
|
||||
if (!elf->getTarget(machine, platform)) {
|
||||
LogError("elf->getTarget() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogPrintfInfo("getTarget(machine=%u, platform=%d)", machine, platform);
|
||||
|
||||
if (machine != target_) {
|
||||
LogPrintfError("machine(%u) != target_(%d)", machine, target_);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (platform != amd::Elf::CPU_PLATFORM) {
|
||||
LogPrintfError("platform(%d) != CAL_PLATFORM(%d)", platform, amd::Elf::CPU_PLATFORM);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t type = ET_NONE;
|
||||
|
||||
if (!elf->getType(type)) {
|
||||
LogError("elf->elf() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogPrintfInfo("getType(%u)", type);
|
||||
|
||||
if(type != ET_EXEC) {
|
||||
LogError("type != ET_EXEC");
|
||||
return false;
|
||||
}
|
||||
|
||||
char* buffer = nullptr;
|
||||
size_t size = 0;
|
||||
|
||||
if (!elf->getSection(amd::Elf::COMMENT, &buffer, &size)) {
|
||||
LogError("elf->getSection(COMMENT) failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogPrintfInfo("getSection(COMMENT, buffer=%s, size=%zu)", buffer, size);
|
||||
|
||||
if(size < commentSize_ || memcmp(comment_, buffer, commentSize_) != 0) {
|
||||
LogPrintfError("Not matched section: size = %zu, buffer = %s, expected: %zu, %s",
|
||||
size, buffer, commentSize_, comment_);
|
||||
return false;
|
||||
}
|
||||
|
||||
LogInfo("Reading rodataSymbolInfo");
|
||||
|
||||
size_t i = 0;
|
||||
buffer = nullptr;
|
||||
size = 0;
|
||||
for (i = 0; i < rodataSymbolInfosSize_; i++) {
|
||||
auto& info = rodataSymbolInfos_[i];
|
||||
if (!elf->getSymbol(amd::Elf::RODATA, info.sym_name.c_str(),
|
||||
&buffer, &size)) {
|
||||
LogPrintfError("elf->getSymbol(RODATA, %s) failed at index %zu", info.sym_name.c_str(), i);
|
||||
return false;
|
||||
}
|
||||
LogPrintfInfo("getSymbol(amd::Elf::RODATA, sym_name=%s, buffer=%s, size=%zu)",
|
||||
info.sym_name.c_str(), buffer, size); // Will possibly print part of buffer
|
||||
|
||||
if(size != info.size || memcmp(buffer, info.address, info.size)) {
|
||||
LogPrintfError("Not matched symbol(%s): size = %zu, buff = %s, expected: %zu, %s",
|
||||
info.sym_name.c_str(), size, buffer, info.size, info.address);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LogInfo("Succeeded");
|
||||
LogInfo("reading commentSymbolInfo");
|
||||
|
||||
buffer = nullptr;
|
||||
size = 0;
|
||||
for (i = 0; i < commentSymbolInfosSize_; i++) {
|
||||
auto& info = commentSymbolInfos_[i];
|
||||
if (!elf->getSymbol(amd::Elf::COMMENT, info.sym_name.c_str(),
|
||||
&buffer, &size)) {
|
||||
LogPrintfError("elf->getSymbol(COMMENT, %s) failed at index %zu", info.sym_name.c_str(), i);
|
||||
return false;
|
||||
}
|
||||
LogPrintfInfo("getSymbol(COMMENT, sym_name=%s, buffer=%s, size=%zu)",
|
||||
info.sym_name.c_str(), buffer, size); // Will possibly print part of buffer
|
||||
if(size != info.size || memcmp(buffer, info.address, info.size)) {
|
||||
LogPrintfError("Not matched symbol(%s): size = %zu, buff = %s, expected: %zu, %s",
|
||||
info.sym_name.c_str(), size, buffer, info.size, info.address);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Test another way
|
||||
auto symbolNum = elf->getSymbolNum();
|
||||
if (symbolNum != (rodataSymbolInfosSize_ + commentSymbolInfosSize_)) {
|
||||
LogPrintfError("Not matched: symbolNum(%u) != rodataSymbolInfosSize_(%u) +" \
|
||||
" commentSymbolInfosSize_(%u)",
|
||||
symbolNum, rodataSymbolInfosSize_, commentSymbolInfosSize_);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < rodataSymbolInfosSize_; i++) {
|
||||
auto &info = rodataSymbolInfos_[i];
|
||||
amd::Elf::SymbolInfo symInfo;
|
||||
|
||||
if (!elf->getSymbolInfo(i, &symInfo)) {
|
||||
LogPrintfError("getSymbolInfo(%zu) failed", i);
|
||||
return false;
|
||||
}
|
||||
LogPrintfInfo("getSymbolInfo(%zu): amd::Elf::RODATA: sec_name=%s, sym_name=%s, " \
|
||||
"address=%s, size=%lu, sec_addr=%s, sec_size=%lu)", i,
|
||||
symInfo.sec_name.c_str(),
|
||||
symInfo.sym_name.c_str(),
|
||||
symInfo.address, // Will possibly print part of buffer
|
||||
symInfo.size,
|
||||
symInfo.sec_addr,
|
||||
symInfo.sec_size);
|
||||
if (symInfo.sec_name == info.sec_name &&
|
||||
symInfo.sym_name == info.sym_name &&
|
||||
symInfo.size == info.size &&
|
||||
::memcmp(symInfo.address, info.address, info.size) == 0) {
|
||||
continue;
|
||||
}
|
||||
LogPrintfError("getSymbolInfo(%zu) returned not matched", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (; i < symbolNum; i++) {
|
||||
auto &info = commentSymbolInfos_[i-rodataSymbolInfosSize_];
|
||||
amd::Elf::SymbolInfo symInfo;
|
||||
|
||||
if (!elf->getSymbolInfo(i, &symInfo)) {
|
||||
LogPrintfError("getSymbolInfo(%zu) failed", i);
|
||||
return false;
|
||||
}
|
||||
LogPrintfInfo("getSymbolInfo(%zu): amd::Elf::COMMENT: sec_name=%s, sym_name=%s, " \
|
||||
"address=%s, size=%lu, sec_addr=%s, sec_size=%lu)", i,
|
||||
symInfo.sec_name.c_str(),
|
||||
symInfo.sym_name.c_str(),
|
||||
symInfo.address, // Will possibly print part of buffer
|
||||
symInfo.size,
|
||||
symInfo.sec_addr,
|
||||
symInfo.sec_size);
|
||||
if (symInfo.sec_name == info.sec_name &&
|
||||
symInfo.sym_name == info.sym_name &&
|
||||
symInfo.size == info.size &&
|
||||
::memcmp(symInfo.address, info.address, info.size) == 0) {
|
||||
continue;
|
||||
}
|
||||
LogPrintfError("getSymbolInfo(%zu) returned not matched", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
LogInfo("Succeeded");
|
||||
LogError("Reading noteInfos");
|
||||
|
||||
buffer = nullptr;
|
||||
size = 0;
|
||||
for (i = 0; i < noteInfosSize_; i++) {
|
||||
auto& info = noteInfos_[i];
|
||||
if (!elf->getNote(info.noteName, &buffer, &size)) {
|
||||
LogPrintfError("elf->getNote(%s) failed at index %zu", info.noteName, i);
|
||||
return false;
|
||||
}
|
||||
// Will possibly print part of buffer
|
||||
LogPrintfInfo("getNote(noteName=%s, buffer=%s, size=%zu)", info.noteName, buffer, size);
|
||||
if(size != info.descSize || memcmp(buffer, info.noteDesc, info.descSize)) {
|
||||
LogPrintfError("Not matched note(%s): size = %zu, buff = %s, expected: %zu, %s",
|
||||
info.noteName, size, buffer, info.descSize, info.noteDesc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LogPrintfInfo("%s: Succeeded", __func__);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test(unsigned char eclass = ELFCLASS64, const char *outFile =
|
||||
nullptr) {
|
||||
amd::Elf *writer = new amd::Elf(eclass, nullptr, 0, outFile,
|
||||
amd::Elf::ELF_C_WRITE);
|
||||
amd::Elf *reader = nullptr;
|
||||
bool ret = false;
|
||||
do {
|
||||
if ((writer == nullptr) || !writer->isSuccessful()) {
|
||||
LogError("Creating writter ELF object failed");
|
||||
break;
|
||||
}
|
||||
|
||||
// Writing
|
||||
if (!set(writer)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Verifying
|
||||
if (!verify(writer)) {
|
||||
break;
|
||||
}
|
||||
|
||||
char *buff = nullptr;
|
||||
unsigned long len = 0;
|
||||
if (writer->dumpImage(&buff, &len)) {
|
||||
LogPrintfInfo("dumpImage succeed: buff=%p, len=%u)", buff, len);
|
||||
|
||||
reader = new amd::Elf(eclass, buff, len, nullptr,
|
||||
amd::Elf::ELF_C_READ);
|
||||
|
||||
delete [] buff;
|
||||
|
||||
if ((reader == nullptr) || !reader->isSuccessful()) {
|
||||
LogError("Creating reader ELF object failed");
|
||||
break;
|
||||
}
|
||||
|
||||
ret = verify(reader);
|
||||
|
||||
delete reader;
|
||||
}
|
||||
} while (false);
|
||||
|
||||
if (writer) {
|
||||
delete writer;
|
||||
}
|
||||
if (reader) {
|
||||
delete reader;
|
||||
}
|
||||
LogPrintfError("%s(%s, %s): %s", __func__, eclass == ELFCLASS64 ? "ELFCLASS64" : "ELFCLASS32",
|
||||
outFile ? outFile : "nullptr", ret ? "Succeeded" : "Failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main() {
|
||||
bool ret = false;
|
||||
amd::Flag::init();
|
||||
unsigned char eclass = LP64_SWITCH(ELFCLASS32, ELFCLASS64);
|
||||
const char *outFile = eclass == ELFCLASS32 ? "elf32.bin" : "elf64.bin";
|
||||
|
||||
ret = test(eclass, outFile);
|
||||
printf("%s: test(%s, %s) %s!\n", __func__,
|
||||
eclass == ELFCLASS32 ? "ELFCLASS32" : "ELFCLASS64", outFile,
|
||||
ret ? "Succeeded" : "Failed");
|
||||
|
||||
if (ret) {
|
||||
ret = test(eclass, nullptr);
|
||||
printf("%s: test(%s, nullptr) %s!\n", __func__,
|
||||
eclass == ELFCLASS32 ? "ELFCLASS32" : "ELFCLASS64",
|
||||
ret ? "Succeeded" : "Failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,542 +0,0 @@
|
||||
/*-
|
||||
* 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 */
|
||||
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@@ -1,47 +0,0 @@
|
||||
#!/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);
|
||||
}'
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#if !defined(_LP64)
|
||||
#define ELFTC_CLASS ELFCLASS32
|
||||
#else
|
||||
#define ELFTC_CLASS ELFCLASS64
|
||||
#endif
|
||||
#define ELFTC_ARCH EM_386
|
||||
#define ELFTC_BYTEORDER ELFDATA2LSB
|
||||
@@ -1,906 +0,0 @@
|
||||
/*
|
||||
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 */
|
||||
@@ -1,12 +0,0 @@
|
||||
#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
|
||||
@@ -1,163 +0,0 @@
|
||||
/*-
|
||||
* 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_ */
|
||||
@@ -1,176 +0,0 @@
|
||||
/*-
|
||||
* 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_ */
|
||||
@@ -1,355 +0,0 @@
|
||||
/*-
|
||||
* 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_ */
|
||||
@@ -1,8 +0,0 @@
|
||||
#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_
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifndef _SYS_PARAM_H_
|
||||
#define _SYS_PARAM_H_ 1
|
||||
|
||||
#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
|
||||
|
||||
#endif
|
||||
@@ -1,673 +0,0 @@
|
||||
/* $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_ */
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
|
||||
file(GLOB sources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/*.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/*.h
|
||||
)
|
||||
|
||||
add_library(oclelf_obj OBJECT ${sources})
|
||||
set_target_properties(oclelf_obj PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
target_include_directories(oclelf_obj
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../common
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../common/win32/sys)
|
||||
|
||||
target_compile_definitions(oclelf_obj
|
||||
PUBLIC
|
||||
BSD_LIBELF USE_MEMFILE)
|
||||
@@ -1,12 +0,0 @@
|
||||
# $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/
|
||||
@@ -1,64 +0,0 @@
|
||||
: 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.
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* $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:
|
||||
*;
|
||||
};
|
||||
@@ -1,218 +0,0 @@
|
||||
/*-
|
||||
* 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_ */
|
||||
@@ -1,56 +0,0 @@
|
||||
/*-
|
||||
* 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_ */
|
||||
@@ -1,289 +0,0 @@
|
||||
/*-
|
||||
* 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
|
||||
@@ -1,41 +0,0 @@
|
||||
/*-
|
||||
* 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 }
|
||||
};
|
||||
@@ -1,337 +0,0 @@
|
||||
/*-
|
||||
* 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
|
||||
@@ -1,58 +0,0 @@
|
||||
/*-
|
||||
* 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;
|
||||
}
|
||||
@@ -1,254 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*-
|
||||
* 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];
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*-
|
||||
* 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;
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
/*-
|
||||
* 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));
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*-
|
||||
* 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));
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*-
|
||||
* 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));
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,246 +0,0 @@
|
||||
/*-
|
||||
* 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));
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*-
|
||||
* 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));
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@@ -1,52 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*-
|
||||
* 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
|
||||
|
||||
#pragma GCC visibility push(hidden)
|
||||
__BEGIN_DECLS
|
||||
long gelf_checksum(Elf *_elf) asm ("rocclr_gelf_checksum");
|
||||
size_t gelf_fsize(Elf *_elf, Elf_Type _type, size_t _count,
|
||||
unsigned int _version) asm ("rocclr_gelf_fsize");
|
||||
int gelf_getclass(Elf *_elf) asm ("rocclr_gelf_getclass");
|
||||
GElf_Dyn *gelf_getdyn(Elf_Data *_data, int _index, GElf_Dyn *_dst) asm ("rocclr_gelf_getdyn");
|
||||
GElf_Ehdr *gelf_getehdr(Elf *_elf, GElf_Ehdr *_dst) asm ("rocclr_gelf_getehdr");
|
||||
GElf_Phdr *gelf_getphdr(Elf *_elf, int _index, GElf_Phdr *_dst) asm ("rocclr_gelf_getphdr");
|
||||
GElf_Rel *gelf_getrel(Elf_Data *_src, int _index, GElf_Rel *_dst) asm ("rocclr_gelf_getrel");
|
||||
GElf_Rela *gelf_getrela(Elf_Data *_src, int _index, GElf_Rela *_dst) asm ("rocclr_gelf_getrela");
|
||||
GElf_Shdr *gelf_getshdr(Elf_Scn *_scn, GElf_Shdr *_dst) asm ("rocclr_gelf_getshdr");
|
||||
GElf_Sym *gelf_getsym(Elf_Data *_src, int _index, GElf_Sym *_dst) asm ("rocclr_gelf_getsym");
|
||||
GElf_Sym *gelf_getsymshndx(Elf_Data *_src, Elf_Data *_shindexsrc,
|
||||
int _index, GElf_Sym *_dst, Elf32_Word *_shindexdst) asm ("rocclr_gelf_getsymshndx");
|
||||
void * gelf_newehdr(Elf *_elf, int _class) asm ("rocclr_gelf_newehdr");
|
||||
void * gelf_newphdr(Elf *_elf, size_t _phnum) asm ("rocclr_gelf_newphdr");
|
||||
int gelf_update_dyn(Elf_Data *_dst, int _index, GElf_Dyn *_src) asm ("rocclr_gelf_update_dyn");
|
||||
int gelf_update_ehdr(Elf *_elf, GElf_Ehdr *_src) asm ("rocclr_gelf_update_ehdr");
|
||||
int gelf_update_phdr(Elf *_elf, int _index, GElf_Phdr *_src) asm ("rocclr_gelf_update_phdr");
|
||||
int gelf_update_rel(Elf_Data *_dst, int _index, GElf_Rel *_src) asm ("rocclr_gelf_update_rel");
|
||||
int gelf_update_rela(Elf_Data *_dst, int _index, GElf_Rela *_src) asm ("rocclr_gelf_update_rela");
|
||||
int gelf_update_shdr(Elf_Scn *_dst, GElf_Shdr *_src) asm ("rocclr_gelf_update_shdr");
|
||||
int gelf_update_sym(Elf_Data *_dst, int _index, GElf_Sym *_src) asm ("rocclr_gelf_update_sym");
|
||||
int gelf_update_symshndx(Elf_Data *_symdst, Elf_Data *_shindexdst,
|
||||
int _index, GElf_Sym *_symsrc, Elf32_Word _shindexsrc) asm ("rocclr_gelf_update_symshndx");
|
||||
Elf_Data *gelf_xlatetof(Elf *_elf, Elf_Data *_dst, const Elf_Data *_src, unsigned int _encode) asm ("rocclr_gelf_xlatetof");
|
||||
Elf_Data *gelf_xlatetom(Elf *_elf, Elf_Data *_dst, const Elf_Data *_src, unsigned int _encode) asm ("rocclr_gelf_xlatetom");
|
||||
|
||||
#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) asm ("rocclr_gelf_getcap");
|
||||
GElf_Move *gelf_getmove(Elf_Data *_src, int _index, GElf_Move *_dst) asm ("rocclr_gelf_getmove");
|
||||
GElf_Syminfo *gelf_getsyminfo(Elf_Data *_src, int _index, GElf_Syminfo *_dst) asm ("rocclr_gelf_getsyminfo");
|
||||
int gelf_update_cap(Elf_Data *_dst, int _index, GElf_Cap *_src) asm ("rocclr_gelf_update_cap");
|
||||
int gelf_update_move(Elf_Data *_dst, int _index, GElf_Move *_src) asm ("rocclr_gelf_update_move");
|
||||
int gelf_update_syminfo(Elf_Data *_dst, int _index, GElf_Syminfo *_src) asm ("rocclr_gelf_update_syminfo");
|
||||
#endif
|
||||
__END_DECLS
|
||||
#pragma GCC visibility pop
|
||||
|
||||
#endif /* _GELF_H_ */
|
||||
@@ -1,148 +0,0 @@
|
||||
/*-
|
||||
* 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 */
|
||||
@@ -1,58 +0,0 @@
|
||||
/*-
|
||||
* 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));
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
/*-
|
||||
* 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 */
|
||||
@@ -1,177 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
/*-
|
||||
* 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 */
|
||||
@@ -1,128 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,264 +0,0 @@
|
||||
/*-
|
||||
* 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 */
|
||||
|
||||
#pragma GCC visibility push(hidden)
|
||||
__BEGIN_DECLS
|
||||
Elf *elf_begin(int _fd, Elf_Cmd _cmd, Elf *_elf, Elf_Mem *_mem) asm ("rocclr_elf_begin");
|
||||
int elf_cntl(Elf *_elf, Elf_Cmd _cmd) asm ("rocclr_elf_cntl");
|
||||
int elf_end(Elf *_elf) asm ("rocclr_elf_end");
|
||||
const char *elf_errmsg(int _error) asm ("rocclr_elf_errmsg");
|
||||
int elf_errno(void) asm ("rocclr_elf_errno");
|
||||
void elf_fill(int _fill) asm ("rocclr_elf_fill");
|
||||
unsigned int elf_flagarhdr(Elf_Arhdr *_arh, Elf_Cmd _cmd,
|
||||
unsigned int _flags) asm ("rocclr_elf_flagarhdr");
|
||||
unsigned int elf_flagdata(Elf_Data *_data, Elf_Cmd _cmd,
|
||||
unsigned int _flags) asm ("rocclr_elf_flagdata");
|
||||
unsigned int elf_flagehdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags) asm ("rocclr_elf_flagehdr");
|
||||
unsigned int elf_flagelf(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags) asm ("rocclr_elf_flagelf");
|
||||
unsigned int elf_flagphdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags) asm ("rocclr_elf_flagphdr");
|
||||
unsigned int elf_flagscn(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags) asm ("rocclr_elf_flagscn");
|
||||
unsigned int elf_flagshdr(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags) asm ("rocclr_elf_flagshdr");
|
||||
Elf_Arhdr *elf_getarhdr(Elf *_elf) asm ("rocclr_elf_getarhdr");
|
||||
Elf_Arsym *elf_getarsym(Elf *_elf, size_t *_ptr) asm ("rocclr_elf_getarsym");
|
||||
off_t elf_getbase(Elf *_elf) asm ("rocclr_elf_getbase");
|
||||
Elf_Data *elf_getdata(Elf_Scn *, Elf_Data *) asm ("rocclr_elf_getdata");
|
||||
void elf_removedata(Elf_Scn *s, Elf_Data *d) asm ("rocclr_elf_removedata");
|
||||
char *elf_getident(Elf *_elf, size_t *_ptr) asm ("rocclr_elf_getident");
|
||||
int elf_getphdrnum(Elf *_elf, size_t *_dst) asm ("rocclr_elf_getphdrnum");
|
||||
int elf_getphnum(Elf *_elf, size_t *_dst) asm ("rocclr_elf_getphnum"); /* Deprecated */
|
||||
Elf_Scn *elf_getscn(Elf *_elf, size_t _index) asm ("rocclr_elf_getscn");
|
||||
int elf_getshdrnum(Elf *_elf, size_t *_dst) asm ("rocclr_elf_getshdrnum");
|
||||
int elf_getshnum(Elf *_elf, size_t *_dst) asm ("rocclr_elf_getshnum"); /* Deprecated */
|
||||
int elf_getshdrstrndx(Elf *_elf, size_t *_dst) asm ("rocclr_elf_getshdrstrndx");
|
||||
int elf_getshstrndx(Elf *_elf, size_t *_dst) asm ("rocclr_elf_getshstrndx"); /* Deprecated */
|
||||
unsigned long elf_hash(const char *_name) asm ("rocclr_elf_hash");
|
||||
Elf_Kind elf_kind(Elf *_elf) asm ("rocclr_elf_kind");
|
||||
Elf *elf_memory(char *_image, size_t _size, Elf_Mem *mem) asm ("rocclr_elf_memory");
|
||||
size_t elf_ndxscn(Elf_Scn *_scn) asm ("rocclr_elf_ndxscn");
|
||||
Elf_Data *elf_newdata(Elf_Scn *_scn) asm ("rocclr_elf_newdata");
|
||||
Elf_Scn *elf_newscn(Elf *_elf) asm ("rocclr_elf_newscn");
|
||||
Elf_Scn *elf_nextscn(Elf *_elf, Elf_Scn *_scn) asm ("rocclr_elf_nextscn");
|
||||
Elf_Cmd elf_next(Elf *_elf) asm ("rocclr_elf_next");
|
||||
off_t elf_rand(Elf *_elf, off_t _off) asm ("rocclr_elf_rand");
|
||||
Elf_Data *elf_rawdata(Elf_Scn *_scn, Elf_Data *_data) asm ("rocclr_elf_rawdata");
|
||||
char *elf_rawfile(Elf *_elf, size_t *_size) asm ("rocclr_elf_rawfile");
|
||||
int elf_setshstrndx(Elf *_elf, size_t _shnum) asm ("rocclr_elf_setshstrndx");
|
||||
char *elf_strptr(Elf *_elf, size_t _section, size_t _offset) asm ("rocclr_elf_strptr");
|
||||
off_t elf_update(Elf *_elf, Elf_Cmd _cmd) asm ("rocclr_elf_update");
|
||||
unsigned int elf_version(unsigned int _version) asm ("rocclr_elf_version");
|
||||
|
||||
long elf32_checksum(Elf *_elf) asm ("rocclr_elf32_checksum");
|
||||
size_t elf32_fsize(Elf_Type _type, size_t _count,
|
||||
unsigned int _version) asm ("rocclr_elf32_fsize");
|
||||
Elf32_Ehdr *elf32_getehdr(Elf *_elf) asm ("rocclr_elf32_getehdr");
|
||||
Elf32_Phdr *elf32_getphdr(Elf *_elf) asm ("rocclr_elf32_getphdr");
|
||||
Elf32_Shdr *elf32_getshdr(Elf_Scn *_scn) asm ("rocclr_elf32_getshdr");
|
||||
Elf32_Ehdr *elf32_newehdr(Elf *_elf) asm ("rocclr_elf32_newehdr");
|
||||
Elf32_Phdr *elf32_newphdr(Elf *_elf, size_t _count) asm ("rocclr_elf32_newphdr");
|
||||
Elf_Data *elf32_xlatetof(Elf_Data *_dst, const Elf_Data *_src,
|
||||
unsigned int _enc) asm ("rocclr_elf32_xlatetof");
|
||||
Elf_Data *elf32_xlatetom(Elf_Data *_dst, const Elf_Data *_src,
|
||||
unsigned int _enc) asm ("rocclr_elf32_xlatetom");
|
||||
|
||||
long elf64_checksum(Elf *_elf) asm ("rocclr_elf64_checksum");
|
||||
size_t elf64_fsize(Elf_Type _type, size_t _count,
|
||||
unsigned int _version) asm ("rocclr_elf64_fsize");
|
||||
Elf64_Ehdr *elf64_getehdr(Elf *_elf) asm ("rocclr_elf64_getehdr");
|
||||
Elf64_Phdr *elf64_getphdr(Elf *_elf) asm ("rocclr_elf64_getphdr");
|
||||
Elf64_Shdr *elf64_getshdr(Elf_Scn *_scn) asm ("rocclr_elf64_getshdr");
|
||||
Elf64_Ehdr *elf64_newehdr(Elf *_elf) asm ("rocclr_elf64_newehdr");
|
||||
Elf64_Phdr *elf64_newphdr(Elf *_elf, size_t _count) asm ("rocclr_elf64_newphdr");
|
||||
Elf_Data *elf64_xlatetof(Elf_Data *_dst, const Elf_Data *_src,
|
||||
unsigned int _enc) asm ("rocclr_elf64_xlatetof");
|
||||
Elf_Data *elf64_xlatetom(Elf_Data *_dst, const Elf_Data *_src,
|
||||
unsigned int _enc) asm ("rocclr_elf64_xlatetom");
|
||||
__END_DECLS
|
||||
#pragma GCC visibility pop
|
||||
|
||||
#endif /* _LIBELF_H_ */
|
||||
@@ -1,185 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,229 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,461 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
@@ -1,354 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*-
|
||||
* 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));
|
||||
}
|
||||
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Ссылка в новой задаче
Block a user