aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-04 19:20:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-08 19:02:26 +0000
commit81ad626541db97eb356e2c1d4a20eb2a26a766ab (patch)
tree311b6a8987c32b1e1dcbab65c54cfac3fdb56175 /contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
parent5fff09660e06a66bed6482da9c70df328e16bbb6 (diff)
parent145449b1e420787bb99721a429341fa6be3adfb6 (diff)
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp')
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp132
1 files changed, 95 insertions, 37 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 96e94ef08a45..28ccfbe3d6e6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -26,6 +26,7 @@
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RangeMap.h"
#include "lldb/Utility/Status.h"
@@ -235,7 +236,7 @@ bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {
const char *cstr = data.GetCStr(offset, llvm::alignTo(n_namesz, 4));
if (cstr == nullptr) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
+ Log *log = GetLog(LLDBLog::Symbols);
LLDB_LOGF(log, "Failed to parse note name lacking nul terminator");
return false;
@@ -309,9 +310,19 @@ static uint32_t riscvVariantFromElfFlags(const elf::ELFHeader &header) {
}
}
+static uint32_t ppc64VariantFromElfFlags(const elf::ELFHeader &header) {
+ uint32_t endian = header.e_ident[EI_DATA];
+ if (endian == ELFDATA2LSB)
+ return ArchSpec::eCore_ppc64le_generic;
+ else
+ return ArchSpec::eCore_ppc64_generic;
+}
+
static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) {
if (header.e_machine == llvm::ELF::EM_MIPS)
return mipsVariantFromElfFlags(header);
+ else if (header.e_machine == llvm::ELF::EM_PPC64)
+ return ppc64VariantFromElfFlags(header);
else if (header.e_machine == llvm::ELF::EM_RISCV)
return riscvVariantFromElfFlags(header);
@@ -335,16 +346,18 @@ void ObjectFileELF::Terminate() {
}
ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
- DataBufferSP &data_sp,
+ DataBufferSP data_sp,
lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
lldb::offset_t file_offset,
lldb::offset_t length) {
+ bool mapped_writable = false;
if (!data_sp) {
- data_sp = MapFileData(*file, length, file_offset);
+ data_sp = MapFileDataWritable(*file, length, file_offset);
if (!data_sp)
return nullptr;
data_offset = 0;
+ mapped_writable = true;
}
assert(data_sp);
@@ -358,10 +371,19 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
// Update the data to contain the entire file if it doesn't already
if (data_sp->GetByteSize() < length) {
- data_sp = MapFileData(*file, length, file_offset);
+ data_sp = MapFileDataWritable(*file, length, file_offset);
if (!data_sp)
return nullptr;
data_offset = 0;
+ mapped_writable = true;
+ magic = data_sp->GetBytes();
+ }
+
+ // If we didn't map the data as writable take ownership of the buffer.
+ if (!mapped_writable) {
+ data_sp = std::make_shared<DataBufferHeap>(data_sp->GetBytes(),
+ data_sp->GetByteSize());
+ data_offset = 0;
magic = data_sp->GetBytes();
}
@@ -378,7 +400,7 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
}
ObjectFile *ObjectFileELF::CreateMemoryInstance(
- const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
+ const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp,
const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) {
if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT)) {
const uint8_t *magic = data_sp->GetBytes();
@@ -504,7 +526,7 @@ size_t ObjectFileELF::GetModuleSpecifications(
const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
lldb::offset_t data_offset, lldb::offset_t file_offset,
lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
+ Log *log = GetLog(LLDBLog::Modules);
const size_t initial_count = specs.GetSize();
@@ -627,7 +649,7 @@ size_t ObjectFileELF::GetModuleSpecifications(
// ObjectFile protocol
ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
- DataBufferSP &data_sp, lldb::offset_t data_offset,
+ DataBufferSP data_sp, lldb::offset_t data_offset,
const FileSpec *file, lldb::offset_t file_offset,
lldb::offset_t length)
: ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset) {
@@ -636,7 +658,7 @@ ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
}
ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
- DataBufferSP &header_data_sp,
+ DataBufferSP header_data_sp,
const lldb::ProcessSP &process_sp,
addr_t header_addr)
: ObjectFile(module_sp, process_sp, header_addr, header_data_sp) {}
@@ -998,7 +1020,7 @@ lldb_private::Status
ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
lldb_private::ArchSpec &arch_spec,
lldb_private::UUID &uuid) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
+ Log *log = GetLog(LLDBLog::Modules);
Status error;
lldb::offset_t offset = 0;
@@ -1174,26 +1196,28 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
// register info
arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
} else if (note.n_name == LLDB_NT_OWNER_CORE) {
- // Parse the NT_FILE to look for stuff in paths to shared libraries As
- // the contents look like this in a 64 bit ELF core file: count =
- // 0x000000000000000a (10) page_size = 0x0000000000001000 (4096) Index
- // start end file_ofs path =====
- // 0x0000000000401000 0x0000000000000000 /tmp/a.out [ 1]
- // 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out [
- // 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out
- // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000
- // /lib/x86_64-linux-gnu/libc-2.19.so [ 4] 0x00007fa79cba8000
- // 0x00007fa79cda7000 0x00000000000001bb /lib/x86_64-linux-
- // gnu/libc-2.19.so [ 5] 0x00007fa79cda7000 0x00007fa79cdab000
- // 0x00000000000001ba /lib/x86_64-linux-gnu/libc-2.19.so [ 6]
- // 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be /lib/x86_64
- // -linux-gnu/libc-2.19.so [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000
- // 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so [ 8]
- // 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 /lib/x86_64
- // -linux-gnu/ld-2.19.so [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000
- // 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so In the 32 bit ELFs
- // the count, page_size, start, end, file_ofs are uint32_t For reference:
- // see readelf source code (in binutils).
+ // Parse the NT_FILE to look for stuff in paths to shared libraries
+ // The contents look like this in a 64 bit ELF core file:
+ //
+ // count = 0x000000000000000a (10)
+ // page_size = 0x0000000000001000 (4096)
+ // Index start end file_ofs path
+ // ===== ------------------ ------------------ ------------------ -------------------------------------
+ // [ 0] 0x0000000000401000 0x0000000000000000 /tmp/a.out
+ // [ 1] 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out
+ // [ 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out
+ // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000 /lib/x86_64-linux-gnu/libc-2.19.so
+ // [ 4] 0x00007fa79cba8000 0x00007fa79cda7000 0x00000000000001bb /lib/x86_64-linux-gnu/libc-2.19.so
+ // [ 5] 0x00007fa79cda7000 0x00007fa79cdab000 0x00000000000001ba /lib/x86_64-linux-gnu/libc-2.19.so
+ // [ 6] 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be /lib/x86_64-linux-gnu/libc-2.19.so
+ // [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so
+ // [ 8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 /lib/x86_64-linux-gnu/ld-2.19.so
+ // [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so
+ //
+ // In the 32 bit ELFs the count, page_size, start, end, file_ofs are
+ // uint32_t.
+ //
+ // For reference: see readelf source code (in binutils).
if (note.n_type == NT_FILE) {
uint64_t count = data.GetAddress(&offset);
const char *cstr;
@@ -1361,11 +1385,33 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float);
}
+ if (arch_spec.GetMachine() == llvm::Triple::riscv32 ||
+ arch_spec.GetMachine() == llvm::Triple::riscv64) {
+ uint32_t flags = arch_spec.GetFlags();
+
+ if (header.e_flags & llvm::ELF::EF_RISCV_RVC)
+ flags |= ArchSpec::eRISCV_rvc;
+ if (header.e_flags & llvm::ELF::EF_RISCV_RVE)
+ flags |= ArchSpec::eRISCV_rve;
+
+ if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE) ==
+ llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE)
+ flags |= ArchSpec::eRISCV_float_abi_single;
+ else if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE) ==
+ llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE)
+ flags |= ArchSpec::eRISCV_float_abi_double;
+ else if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD) ==
+ llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD)
+ flags |= ArchSpec::eRISCV_float_abi_quad;
+
+ arch_spec.SetFlags(flags);
+ }
+
// If there are no section headers we are done.
if (header.e_shnum == 0)
return 0;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
+ Log *log = GetLog(LLDBLog::Modules);
section_headers.resize(header.e_shnum);
if (section_headers.size() != header.e_shnum)
@@ -1678,9 +1724,9 @@ class VMAddressProvider {
ObjectFile::Type ObjectType;
addr_t NextVMAddress = 0;
VMMap::Allocator Alloc;
- VMMap Segments = VMMap(Alloc);
- VMMap Sections = VMMap(Alloc);
- lldb_private::Log *Log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES);
+ VMMap Segments{Alloc};
+ VMMap Sections{Alloc};
+ lldb_private::Log *Log = GetLog(LLDBLog::Modules);
size_t SegmentCount = 0;
std::string SegmentName;
@@ -2596,8 +2642,11 @@ unsigned ObjectFileELF::ApplyRelocations(
if (symbol) {
addr_t value = symbol->GetAddressRef().GetFileAddress();
DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
+ // ObjectFileELF creates a WritableDataBuffer in CreateInstance.
+ WritableDataBuffer *data_buffer =
+ llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
uint64_t *dst = reinterpret_cast<uint64_t *>(
- data_buffer_sp->GetBytes() + rel_section->GetFileOffset() +
+ data_buffer->GetBytes() + rel_section->GetFileOffset() +
ELFRelocation::RelocOffset64(rel));
uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel);
memcpy(dst, &val_offset, sizeof(uint64_t));
@@ -2616,15 +2665,17 @@ unsigned ObjectFileELF::ApplyRelocations(
((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN)) ||
(reloc_type(rel) == R_AARCH64_ABS32 &&
((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN))) {
- Log *log =
- lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES);
+ Log *log = GetLog(LLDBLog::Modules);
LLDB_LOGF(log, "Failed to apply debug info relocations");
break;
}
uint32_t truncated_addr = (value & 0xFFFFFFFF);
DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
+ // ObjectFileELF creates a WritableDataBuffer in CreateInstance.
+ WritableDataBuffer *data_buffer =
+ llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
uint32_t *dst = reinterpret_cast<uint32_t *>(
- data_buffer_sp->GetBytes() + rel_section->GetFileOffset() +
+ data_buffer->GetBytes() + rel_section->GetFileOffset() +
ELFRelocation::RelocOffset32(rel));
memcpy(dst, &truncated_addr, sizeof(uint32_t));
}
@@ -3388,3 +3439,10 @@ ObjectFileELF::GetLoadableData(Target &target) {
}
return loadables;
}
+
+lldb::WritableDataBufferSP
+ObjectFileELF::MapFileDataWritable(const FileSpec &file, uint64_t Size,
+ uint64_t Offset) {
+ return FileSystem::Instance().CreateWritableDataBuffer(file.GetPath(), Size,
+ Offset);
+}