Skip to content

Commit

Permalink
elf/symbol: Symbol link to program headers
Browse files Browse the repository at this point in the history
GElf_Sym belongs to a section, and this section could belongs to more
than one Phdrs.

    $ ./src/tests/ulpatch_test -f Elf.for_each_symbol -v
    ...
     0x000000000051c120 424     OBJECT   LOCAL    INTERNAL     16   x86_64_reloc_map
      Type             Offset             VirtAddr           PhysAddr
                       FileSize           MemSize            Flags    Align
      LOAD             0x00000000000f4000 0x00000000004f4000 00000000004f4000
                       0x0000000000045d98 0x0000000000045d98 R        00001000
     0x000000000054b4a0 904     OBJECT   GLOBAL   INTERNAL     22   x86_64_pei_vec
      Type             Offset             VirtAddr           PhysAddr
                       FileSize           MemSize            Flags    Align
      LOAD             0x000000000013a020 0x000000000053a020 000000000053a020
                       0x00000000000290f0 0x000000000002a5b8 RW       00001000
      GNU_RELRO        0x000000000013a020 0x000000000053a020 000000000053a020
                       0x0000000000014fe0 0x0000000000014fe0 R        00000001

Signed-off-by: Rong Tao <[email protected]>
  • Loading branch information
Rtoax committed Jul 28, 2024
1 parent 1cdfc19 commit 3fa9c60
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 3 deletions.
7 changes: 7 additions & 0 deletions src/elf/elf_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ struct symbol {
char *name;
GElf_Sym sym;

/**
* If symbol from ELF file, point to elf file phdrs. If symbol from
* VMA mem, point to vma's elf phdrs, and used to locate VMA.
*/
int nphdrs;
GElf_Phdr *phdrs;

/**
* Maybe belongs to a VMA, and this vma is ELF format, which is the
* leader of all other PT_LOAD vmas.
Expand Down
35 changes: 32 additions & 3 deletions src/elf/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,14 +367,43 @@ int for_each_symbol(struct elf_file *elf, void (*handler)(struct elf_file *,
/* Insert OK, return 0, else return -1 */
int link_symbol(struct elf_file *elf, struct symbol *s)
{
struct rb_node *node = rb_insert_node(&elf->elf_file_symbols, &s->node,
cmp_symbol_name,
(unsigned long)s);
int i, nphdrs;
struct rb_node *node;
GElf_Section sec = s->sym.st_shndx;
GElf_Shdr *shdr = &elf->shdrs[sec];

if (!is_undef_symbol(&s->sym)) {
GElf_Phdr *phdr, *phdrs;

nphdrs = 0;
phdrs = malloc(sizeof(GElf_Phdr) * elf->phdrnum);

for (i = 0; i < elf->phdrnum; i++) {
phdr = &elf->phdrs[i];
if (shdr->sh_offset >= phdr->p_offset &&
shdr->sh_offset + shdr->sh_size <=
phdr->p_offset + phdr->p_filesz) {
memcpy(&phdrs[nphdrs], phdr, sizeof(GElf_Phdr));
nphdrs++;
}
}
if (nphdrs) {
s->nphdrs = nphdrs;
s->phdrs = malloc(sizeof(GElf_Phdr) * nphdrs);
memcpy(s->phdrs, phdrs, sizeof(GElf_Phdr) * nphdrs);
}
free(phdrs);
}

node = rb_insert_node(&elf->elf_file_symbols, &s->node,
cmp_symbol_name, (unsigned long)s);
return node ? -1 : 0;
}

void free_symbol(struct symbol *s)
{
if (s->phdrs)
free(s->phdrs);
free(s->name);
free(s);
}
Expand Down
7 changes: 7 additions & 0 deletions src/tests/elf/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,15 @@ static const struct symbol_t symbols[] = {
static void print_elf_symbol(struct elf_file *elf, struct symbol *sym,
void *arg)
{
int i;
static bool firstline = true;

fprint_sym(stdout, &sym->sym, sym->name, NULL, firstline);
if (sym->nphdrs > 0) {
for (i = 0; i < sym->nphdrs; i++)
print_phdr(stdout, &sym->phdrs[i], i == 0);
}

firstline = false;
}

Expand Down
5 changes: 5 additions & 0 deletions src/utils/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,11 @@ int task_vma_link_symbol(struct symbol *s, struct vm_area_struct *leader)
fprint_sym(get_log_fp(), &s->sym, s->name, NULL, true);

s->vma = vma;

/**
* TODO: Get the symbol belongs to which phdrs.
*/

node = rb_insert_node(&task->vma_symbols, &s->node, cmp_symbol_name,
(unsigned long)s);
if (unlikely(node))
Expand Down

0 comments on commit 3fa9c60

Please sign in to comment.