mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2025-03-06 21:49:44 +00:00
Simplify ELF parser code.
The layout of Elf32_Nhdr and Elf64_Nhdr is the same, so remove templating and code that extracts the elfclass from the ELF file. Testing: "make check" and breakpad_unittests when patched into chromium. Bug: chromium:716484 Change-Id: I41442cfff48afc6ae1a5b604d22b67550a910376 Reviewed-on: https://chromium-review.googlesource.com/514450 Reviewed-by: Mike Frysinger <vapier@chromium.org>
This commit is contained in:
parent
77305c3ae6
commit
fbfd41af5f
|
@ -352,17 +352,16 @@ bool ElfFileSoNameFromMappedFile(
|
||||||
|
|
||||||
const void* segment_start;
|
const void* segment_start;
|
||||||
size_t segment_size;
|
size_t segment_size;
|
||||||
int elf_class;
|
if (!FindElfSection(elf_base, ".dynamic", SHT_DYNAMIC, &segment_start,
|
||||||
if (!FindElfSection(elf_base, ".dynamic", SHT_DYNAMIC,
|
&segment_size)) {
|
||||||
&segment_start, &segment_size, &elf_class)) {
|
|
||||||
// No dynamic section
|
// No dynamic section
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const void* dynstr_start;
|
const void* dynstr_start;
|
||||||
size_t dynstr_size;
|
size_t dynstr_size;
|
||||||
if (!FindElfSection(elf_base, ".dynstr", SHT_STRTAB,
|
if (!FindElfSection(elf_base, ".dynstr", SHT_STRTAB, &dynstr_start,
|
||||||
&dynstr_start, &dynstr_size, &elf_class)) {
|
&dynstr_size)) {
|
||||||
// No dynstr section
|
// No dynstr section
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,8 +122,7 @@ bool FindElfSection(const void *elf_mapped_base,
|
||||||
const char *section_name,
|
const char *section_name,
|
||||||
uint32_t section_type,
|
uint32_t section_type,
|
||||||
const void **section_start,
|
const void **section_start,
|
||||||
size_t *section_size,
|
size_t *section_size) {
|
||||||
int *elfclass) {
|
|
||||||
assert(elf_mapped_base);
|
assert(elf_mapped_base);
|
||||||
assert(section_start);
|
assert(section_start);
|
||||||
assert(section_size);
|
assert(section_size);
|
||||||
|
@ -135,10 +134,6 @@ bool FindElfSection(const void *elf_mapped_base,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int cls = ElfClass(elf_mapped_base);
|
int cls = ElfClass(elf_mapped_base);
|
||||||
if (elfclass) {
|
|
||||||
*elfclass = cls;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* elf_base =
|
const char* elf_base =
|
||||||
static_cast<const char*>(elf_mapped_base);
|
static_cast<const char*>(elf_mapped_base);
|
||||||
|
|
||||||
|
@ -158,8 +153,7 @@ bool FindElfSection(const void *elf_mapped_base,
|
||||||
bool FindElfSegment(const void *elf_mapped_base,
|
bool FindElfSegment(const void *elf_mapped_base,
|
||||||
uint32_t segment_type,
|
uint32_t segment_type,
|
||||||
const void **segment_start,
|
const void **segment_start,
|
||||||
size_t *segment_size,
|
size_t *segment_size) {
|
||||||
int *elfclass) {
|
|
||||||
assert(elf_mapped_base);
|
assert(elf_mapped_base);
|
||||||
assert(segment_start);
|
assert(segment_start);
|
||||||
assert(segment_size);
|
assert(segment_size);
|
||||||
|
@ -171,10 +165,6 @@ bool FindElfSegment(const void *elf_mapped_base,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int cls = ElfClass(elf_mapped_base);
|
int cls = ElfClass(elf_mapped_base);
|
||||||
if (elfclass) {
|
|
||||||
*elfclass = cls;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* elf_base =
|
const char* elf_base =
|
||||||
static_cast<const char*>(elf_mapped_base);
|
static_cast<const char*>(elf_mapped_base);
|
||||||
|
|
||||||
|
|
|
@ -81,14 +81,12 @@ int ElfClass(const void* elf_base);
|
||||||
// Attempt to find a section named |section_name| of type |section_type|
|
// Attempt to find a section named |section_name| of type |section_type|
|
||||||
// in the ELF binary data at |elf_mapped_base|. On success, returns true
|
// in the ELF binary data at |elf_mapped_base|. On success, returns true
|
||||||
// and sets |*section_start| to point to the start of the section data,
|
// and sets |*section_start| to point to the start of the section data,
|
||||||
// and |*section_size| to the size of the section's data. If |elfclass|
|
// and |*section_size| to the size of the section's data.
|
||||||
// is not NULL, set |*elfclass| to the ELF file class.
|
|
||||||
bool FindElfSection(const void *elf_mapped_base,
|
bool FindElfSection(const void *elf_mapped_base,
|
||||||
const char *section_name,
|
const char *section_name,
|
||||||
uint32_t section_type,
|
uint32_t section_type,
|
||||||
const void **section_start,
|
const void **section_start,
|
||||||
size_t *section_size,
|
size_t *section_size);
|
||||||
int *elfclass);
|
|
||||||
|
|
||||||
// Internal helper method, exposed for convenience for callers
|
// Internal helper method, exposed for convenience for callers
|
||||||
// that already have more info.
|
// that already have more info.
|
||||||
|
@ -104,13 +102,11 @@ FindElfSectionByName(const char* name,
|
||||||
// Attempt to find the first segment of type |segment_type| in the ELF
|
// Attempt to find the first segment of type |segment_type| in the ELF
|
||||||
// binary data at |elf_mapped_base|. On success, returns true and sets
|
// binary data at |elf_mapped_base|. On success, returns true and sets
|
||||||
// |*segment_start| to point to the start of the segment data, and
|
// |*segment_start| to point to the start of the segment data, and
|
||||||
// and |*segment_size| to the size of the segment's data. If |elfclass|
|
// and |*segment_size| to the size of the segment's data.
|
||||||
// is not NULL, set |*elfclass| to the ELF file class.
|
|
||||||
bool FindElfSegment(const void *elf_mapped_base,
|
bool FindElfSegment(const void *elf_mapped_base,
|
||||||
uint32_t segment_type,
|
uint32_t segment_type,
|
||||||
const void **segment_start,
|
const void **segment_start,
|
||||||
size_t *segment_size,
|
size_t *segment_size);
|
||||||
int *elfclass);
|
|
||||||
|
|
||||||
// Convert an offset from an Elf header into a pointer to the mapped
|
// Convert an offset from an Elf header into a pointer to the mapped
|
||||||
// address in the current process. Takes an extra template parameter
|
// address in the current process. Takes an extra template parameter
|
||||||
|
|
|
@ -61,10 +61,11 @@ FileID::FileID(const char* path) : path_(path) {}
|
||||||
// These functions are also used inside the crashed process, so be safe
|
// These functions are also used inside the crashed process, so be safe
|
||||||
// and use the syscall/libc wrappers instead of direct syscalls or libc.
|
// and use the syscall/libc wrappers instead of direct syscalls or libc.
|
||||||
|
|
||||||
template<typename ElfClass>
|
|
||||||
static bool ElfClassBuildIDNoteIdentifier(const void *section, size_t length,
|
static bool ElfClassBuildIDNoteIdentifier(const void *section, size_t length,
|
||||||
wasteful_vector<uint8_t>& identifier) {
|
wasteful_vector<uint8_t>& identifier) {
|
||||||
typedef typename ElfClass::Nhdr Nhdr;
|
static_assert(sizeof(ElfClass32::Nhdr) == sizeof(ElfClass64::Nhdr),
|
||||||
|
"Elf32_Nhdr and Elf64_Nhdr should be the same");
|
||||||
|
typedef typename ElfClass32::Nhdr Nhdr;
|
||||||
|
|
||||||
const void* section_end = reinterpret_cast<const char*>(section) + length;
|
const void* section_end = reinterpret_cast<const char*>(section) + length;
|
||||||
const Nhdr* note_header = reinterpret_cast<const Nhdr*>(section);
|
const Nhdr* note_header = reinterpret_cast<const Nhdr*>(section);
|
||||||
|
@ -96,25 +97,16 @@ static bool FindElfBuildIDNote(const void* elf_mapped_base,
|
||||||
wasteful_vector<uint8_t>& identifier) {
|
wasteful_vector<uint8_t>& identifier) {
|
||||||
void* note_section;
|
void* note_section;
|
||||||
size_t note_size;
|
size_t note_size;
|
||||||
int elfclass;
|
|
||||||
if ((!FindElfSegment(elf_mapped_base, PT_NOTE,
|
if ((!FindElfSegment(elf_mapped_base, PT_NOTE,
|
||||||
(const void**)¬e_section, ¬e_size, &elfclass) ||
|
(const void**)¬e_section, ¬e_size) ||
|
||||||
note_size == 0) &&
|
note_size == 0) &&
|
||||||
(!FindElfSection(elf_mapped_base, ".note.gnu.build-id", SHT_NOTE,
|
(!FindElfSection(elf_mapped_base, ".note.gnu.build-id", SHT_NOTE,
|
||||||
(const void**)¬e_section, ¬e_size, &elfclass) ||
|
(const void**)¬e_section, ¬e_size) ||
|
||||||
note_size == 0)) {
|
note_size == 0)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elfclass == ELFCLASS32) {
|
return ElfClassBuildIDNoteIdentifier(note_section, note_size, identifier);
|
||||||
return ElfClassBuildIDNoteIdentifier<ElfClass32>(note_section, note_size,
|
|
||||||
identifier);
|
|
||||||
} else if (elfclass == ELFCLASS64) {
|
|
||||||
return ElfClassBuildIDNoteIdentifier<ElfClass64>(note_section, note_size,
|
|
||||||
identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to locate the .text section of an ELF binary and generate
|
// Attempt to locate the .text section of an ELF binary and generate
|
||||||
|
@ -126,7 +118,7 @@ static bool HashElfTextSection(const void* elf_mapped_base,
|
||||||
void* text_section;
|
void* text_section;
|
||||||
size_t text_size;
|
size_t text_size;
|
||||||
if (!FindElfSection(elf_mapped_base, ".text", SHT_PROGBITS,
|
if (!FindElfSection(elf_mapped_base, ".text", SHT_PROGBITS,
|
||||||
(const void**)&text_section, &text_size, NULL) ||
|
(const void**)&text_section, &text_size) ||
|
||||||
text_size == 0) {
|
text_size == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue