}
static int pakfire_elf_get_section(struct pakfire_elf* self,
- const Elf64_Word type, Elf_Scn** section, GElf_Shdr* header, Elf_Data** data) {
+ const Elf64_Word type, const char* name, Elf_Scn** section, GElf_Shdr* header, Elf_Data** data) {
+ const char* sname = NULL;
Elf_Scn* s = NULL;
GElf_Shdr shdr;
+ int r;
+
+ size_t shstrndx = 0;
+
+ // Find the strings
+ r = elf_getshdrstrndx(self->elf, &shstrndx);
+ if (r < 0) {
+ ERROR(self->ctx, "elf_getshdrstrndx() failed: %s\n", elf_errmsg(-1));
+ return r;
+ }
// Walk through all sections
for (;;) {
// Return any matching sections
if (shdr.sh_type == type) {
+ // If we have a name, check it too
+ if (name) {
+ sname = elf_strptr(self->elf, shstrndx, shdr.sh_name);
+ if (!sname)
+ continue;
+
+ // Skip if the name does not match
+ if (!pakfire_string_equals(name, sname))
+ continue;
+ }
+
+ // Return a pointer to the section
*section = s;
// Send header if requested
int r;
// Find the dynamic linking information
- r = pakfire_elf_get_section(self, SHT_DYNAMIC, &dynamic, &shdr, &elf_data);
+ r = pakfire_elf_get_section(self, SHT_DYNAMIC, NULL, &dynamic, &shdr, &elf_data);
if (r) {
DEBUG(self->ctx, "%s does not have a dynamic section\n", self->path);
return r;
}
int pakfire_elf_has_ssp(struct pakfire_elf* self) {
- const char* name = NULL;
- Elf_Scn* symtab = NULL;
- GElf_Shdr shdr;
- Elf_Data* data = NULL;
- GElf_Sym symbol;
+ GElf_Sym symbol = {};
int r;
- // Fetch the symbol table
- r = pakfire_elf_get_section(self, SHT_SYMTAB, &symtab, &shdr, &data);
+ // .dynsym
+ Elf_Scn* dynsym = NULL;
+ GElf_Shdr symhdr = {};
+ Elf_Data* symdata = NULL;
+
+ // .dynstr
+ Elf_Scn* dynstr = NULL;
+ GElf_Shdr strhdr = {};
+ Elf_Data* strdata = NULL;
+
+ // Fetch .dynsym
+ r = pakfire_elf_get_section(self, SHT_DYNSYM, NULL, &dynsym, &symhdr, &symdata);
+ if (r) {
+ DEBUG(self->ctx, "%s has no .dynsym section\n", self->path);
+ return 0;
+ }
+
+ // Fetch .dynstr
+ r = pakfire_elf_get_section(self, SHT_STRTAB, ".dynstr", &dynstr, &strhdr, &strdata);
if (r) {
- DEBUG(self->ctx, "%s has no symbol table\n", self->path);
+ DEBUG(self->ctx, "%s has no .dynstr section\n", self->path);
return 0;
}
size_t counter = 0;
// Walk through all symbols
- for (unsigned int i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) {
- gelf_getsym(data, i, &symbol);
+ for (unsigned int i = 0; i < symhdr.sh_size / symhdr.sh_entsize; i++) {
+ gelf_getsym(symdata, i, &symbol);
// Fetch the symbol name
- name = elf_strptr(self->elf, shdr.sh_link, symbol.st_name);
+ const char* name = elf_strptr(self->elf, elf_ndxscn(dynstr), symbol.st_name);
// Skip empty section names
if (!name || !*name)
}
// Fetch the symbol table
- return pakfire_elf_get_section(self, SHT_SYMTAB, &symtab, NULL, NULL);
+ return pakfire_elf_get_section(self, SHT_SYMTAB, NULL, &symtab, NULL, NULL);
}