diff options
| -rw-r--r-- | sys/alpha/alpha/elf_machdep.c | 21 | ||||
| -rw-r--r-- | sys/amd64/amd64/elf_machdep.c | 18 | ||||
| -rw-r--r-- | sys/i386/i386/elf_machdep.c | 18 | ||||
| -rw-r--r-- | sys/ia64/ia64/elf_machdep.c | 43 | ||||
| -rw-r--r-- | sys/kern/link_elf.c | 63 | ||||
| -rw-r--r-- | sys/kern/link_elf_obj.c | 63 | ||||
| -rw-r--r-- | sys/powerpc/powerpc/elf_machdep.c | 16 | ||||
| -rw-r--r-- | sys/sparc64/sparc64/elf_machdep.c | 7 | ||||
| -rw-r--r-- | sys/sys/linker.h | 5 |
9 files changed, 168 insertions, 86 deletions
diff --git a/sys/alpha/alpha/elf_machdep.c b/sys/alpha/alpha/elf_machdep.c index cdb27c50955a..ebd3b60d204c 100644 --- a/sys/alpha/alpha/elf_machdep.c +++ b/sys/alpha/alpha/elf_machdep.c @@ -38,13 +38,13 @@ /* Process one elf relocation with addend. */ int -elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) +elf_reloc(linker_file_t lf, const void *data, int type) { Elf_Addr relocbase = (Elf_Addr) lf->address; Elf_Addr *where; Elf_Addr addr; Elf_Addr addend; - Elf_Word rtype; + Elf_Word rtype, symidx; const Elf_Rel *rel; const Elf_Rela *rela; @@ -54,12 +54,14 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) where = (Elf_Addr *) (relocbase + rel->r_offset); addend = *where; rtype = ELF_R_TYPE(rel->r_info); + symidx = ELF_R_SYM(rel->r_info); break; case ELF_RELOC_RELA: rela = (const Elf_Rela *)data; where = (Elf_Addr *) (relocbase + rela->r_offset); addend = rela->r_addend; rtype = ELF_R_TYPE(rela->r_info); + symidx = ELF_R_SYM(rela->r_info); break; default: panic("elf_reloc: unknown relocation mode %d\n", type); @@ -71,9 +73,8 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) break; case R_ALPHA_REFQUAD: - addr = (Elf_Addr) - linker_file_lookup_symbol(lf, sym, 1); - if (addr == NULL) + addr = elf_lookup(lf, symidx, 1); + if (addr == 0) return -1; addr += addend; if (*where != addr) @@ -81,9 +82,8 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) break; case R_ALPHA_GLOB_DAT: - addr = (Elf_Addr) - linker_file_lookup_symbol(lf, sym, 1); - if (addr == NULL) + addr = elf_lookup(lf, symidx, 1); + if (addr == 0) return -1; addr += addend; if (*where != addr) @@ -92,9 +92,8 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) case R_ALPHA_JMP_SLOT: /* No point in lazy binding for kernel modules. */ - addr = (Elf_Addr) - linker_file_lookup_symbol(lf, sym, 1); - if (addr == NULL) + addr = elf_lookup(lf, symidx, 1); + if (addr == 0) return -1; if (*where != addr) *where = addr; diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c index 577aeac1c45c..96d91b00c04d 100644 --- a/sys/amd64/amd64/elf_machdep.c +++ b/sys/amd64/amd64/elf_machdep.c @@ -32,13 +32,13 @@ /* Process one elf relocation with addend. */ int -elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) +elf_reloc(linker_file_t lf, const void *data, int type) { Elf_Addr relocbase = (Elf_Addr) lf->address; Elf_Addr *where; Elf_Addr addr; Elf_Addr addend; - Elf_Word rtype; + Elf_Word rtype, symidx; const Elf_Rel *rel; const Elf_Rela *rela; @@ -48,12 +48,14 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) where = (Elf_Addr *) (relocbase + rel->r_offset); addend = *where; rtype = ELF_R_TYPE(rel->r_info); + symidx = ELF_R_SYM(rel->r_info); break; case ELF_RELOC_RELA: rela = (const Elf_Rela *)data; where = (Elf_Addr *) (relocbase + rela->r_offset); addend = rela->r_addend; rtype = ELF_R_TYPE(rela->r_info); + symidx = ELF_R_SYM(rela->r_info); break; default: panic("unknown reloc type %d\n", type); @@ -65,9 +67,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) break; case R_386_32: /* S + A */ - if (sym == NULL) - return -1; - addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); + addr = elf_lookup(lf, symidx, 1); if (addr == 0) return -1; addr += addend; @@ -76,9 +76,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) break; case R_386_PC32: /* S + A - P */ - if (sym == NULL) - return -1; - addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); + addr = elf_lookup(lf, symidx, 1); if (addr == 0) return -1; addr += addend - (Elf_Addr)where; @@ -96,9 +94,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) break; case R_386_GLOB_DAT: /* S */ - if (sym == NULL) - return -1; - addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); + addr = elf_lookup(lf, symidx, 1); if (addr == 0) return -1; if (*where != addr) diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c index 577aeac1c45c..96d91b00c04d 100644 --- a/sys/i386/i386/elf_machdep.c +++ b/sys/i386/i386/elf_machdep.c @@ -32,13 +32,13 @@ /* Process one elf relocation with addend. */ int -elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) +elf_reloc(linker_file_t lf, const void *data, int type) { Elf_Addr relocbase = (Elf_Addr) lf->address; Elf_Addr *where; Elf_Addr addr; Elf_Addr addend; - Elf_Word rtype; + Elf_Word rtype, symidx; const Elf_Rel *rel; const Elf_Rela *rela; @@ -48,12 +48,14 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) where = (Elf_Addr *) (relocbase + rel->r_offset); addend = *where; rtype = ELF_R_TYPE(rel->r_info); + symidx = ELF_R_SYM(rel->r_info); break; case ELF_RELOC_RELA: rela = (const Elf_Rela *)data; where = (Elf_Addr *) (relocbase + rela->r_offset); addend = rela->r_addend; rtype = ELF_R_TYPE(rela->r_info); + symidx = ELF_R_SYM(rela->r_info); break; default: panic("unknown reloc type %d\n", type); @@ -65,9 +67,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) break; case R_386_32: /* S + A */ - if (sym == NULL) - return -1; - addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); + addr = elf_lookup(lf, symidx, 1); if (addr == 0) return -1; addr += addend; @@ -76,9 +76,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) break; case R_386_PC32: /* S + A - P */ - if (sym == NULL) - return -1; - addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); + addr = elf_lookup(lf, symidx, 1); if (addr == 0) return -1; addr += addend - (Elf_Addr)where; @@ -96,9 +94,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) break; case R_386_GLOB_DAT: /* S */ - if (sym == NULL) - return -1; - addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); + addr = elf_lookup(lf, symidx, 1); if (addr == 0) return -1; if (*where != addr) diff --git a/sys/ia64/ia64/elf_machdep.c b/sys/ia64/ia64/elf_machdep.c index 9ecfe71f1711..dcee3a454739 100644 --- a/sys/ia64/ia64/elf_machdep.c +++ b/sys/ia64/ia64/elf_machdep.c @@ -41,24 +41,24 @@ Elf_Addr link_elf_get_gp(linker_file_t); extern Elf_Addr fptr_storage[]; static Elf_Addr -lookup_fdesc(linker_file_t lf, const char *sym) +lookup_fdesc(linker_file_t lf, Elf_Word symidx) { Elf_Addr addr; int i; static int eot = 0; - addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 0); - if (addr == NULL) { + addr = elf_lookup(lf, symidx, 0); + if (addr == 0) { for (i = 0; i < lf->ndeps; i++) { - addr = lookup_fdesc(lf->deps[i], sym); - if (addr != NULL) + addr = lookup_fdesc(lf->deps[i], symidx); + if (addr != 0) return (addr); } - return (NULL); + return (0); } if (eot) - return (NULL); + return (0); /* * Lookup and/or construct OPD @@ -77,17 +77,17 @@ lookup_fdesc(linker_file_t lf, const char *sym) printf("%s: fptr table full\n", __func__); eot = 1; - return (NULL); + return (0); } /* Process one elf relocation with addend. */ int -elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) +elf_reloc(linker_file_t lf, const void *data, int type) { Elf_Addr relocbase = (Elf_Addr)lf->address; Elf_Addr *where; Elf_Addr addend, addr; - Elf_Word rtype; + Elf_Word rtype, symidx; const Elf_Rel *rel; const Elf_Rela *rela; @@ -96,6 +96,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) rel = (const Elf_Rel *)data; where = (Elf_Addr *)(relocbase + rel->r_offset); rtype = ELF_R_TYPE(rel->r_info); + symidx = ELF_R_SYM(rel->r_info); switch (rtype) { case R_IA64_DIR64LSB: case R_IA64_FPTR64LSB: @@ -111,6 +112,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) rela = (const Elf_Rela *)data; where = (Elf_Addr *)(relocbase + rela->r_offset); rtype = ELF_R_TYPE(rela->r_info); + symidx = ELF_R_SYM(rela->r_info); addend = rela->r_addend; break; default: @@ -121,35 +123,28 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) case R_IA64_NONE: break; case R_IA64_DIR64LSB: /* word64 LSB S + A */ - if (sym == NULL) - return -1; - addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); + addr = elf_lookup(lf, symidx, 1); if (addr == 0) - return -1; + return (-1); *where = addr + addend; break; case R_IA64_FPTR64LSB: /* word64 LSB @fptr(S + A) */ - if (sym == NULL) - return -1; if (addend != 0) { printf("%s: addend ignored for OPD relocation\n", __func__); } - addr = lookup_fdesc(lf, sym); + addr = lookup_fdesc(lf, symidx); if (addr == 0) - return -1; + return (-1); *where = addr; break; case R_IA64_REL64LSB: /* word64 LSB BD + A */ *where = relocbase + addend; break; case R_IA64_IPLTLSB: - if (sym == NULL) - return -1; - /* lookup_fdesc() returns the address of the OPD. */ - addr = lookup_fdesc(lf, sym); + addr = lookup_fdesc(lf, symidx); if (addr == 0) - return -1; + return (-1); where[0] = *((Elf_Addr*)addr) + addend; where[1] = *((Elf_Addr*)addr + 1); break; @@ -159,5 +154,5 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) return -1; } - return(0); + return (0); } diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c index 8eb7681f95ac..dd594051a998 100644 --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.c @@ -904,8 +904,8 @@ relocate_file(elf_file_t ef) if (rel) { rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize); while (rel < rellim) { - symname = symbol_name(ef, rel->r_info); - if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, symname)) { + if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) { + symname = symbol_name(ef, rel->r_info); printf("link_elf: symbol %s undefined\n", symname); return ENOENT; } @@ -918,8 +918,8 @@ relocate_file(elf_file_t ef) if (rela) { relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize); while (rela < relalim) { - symname = symbol_name(ef, rela->r_info); - if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, symname)) { + if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) { + symname = symbol_name(ef, rela->r_info); printf("link_elf: symbol %s undefined\n", symname); return ENOENT; } @@ -932,8 +932,8 @@ relocate_file(elf_file_t ef) if (rel) { rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize); while (rel < rellim) { - symname = symbol_name(ef, rel->r_info); - if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, symname)) { + if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) { + symname = symbol_name(ef, rel->r_info); printf("link_elf: symbol %s undefined\n", symname); return ENOENT; } @@ -946,8 +946,8 @@ relocate_file(elf_file_t ef) if (rela) { relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize); while (rela < relalim) { - symname = symbol_name(ef, rela->r_info); - if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, symname)) { + if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) { + symname = symbol_name(ef, rela->r_info); printf("link_elf: symbol %s undefined\n", symname); return ENOENT; } @@ -1190,3 +1190,50 @@ link_elf_get_gp(linker_file_t lf) return (Elf_Addr)ef->got; } #endif + +/* + * Symbol lookup function that can be used when the symbol index is known (ie + * in relocations). It uses the symbol index instead of doing a fully fledged + * hash table based lookup when such is valid. For example for local symbols. + * This is not only more efficient, it's also more correct. It's not always + * the case that the symbol can be found through the hash table. + */ +Elf_Addr +elf_lookup(linker_file_t lf, Elf_Word symidx, int deps) +{ + elf_file_t ef = (elf_file_t)lf; + const Elf_Sym *sym; + const char *symbol; + + /* Don't even try to lookup the symbol if the index is bogus. */ + if (symidx >= ef->nchains) + return (0); + + sym = ef->symtab + symidx; + + /* + * Don't do a full lookup when the symbol is local. It may even + * fail because it may not be found through the hash table. + */ + if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) { + /* Force lookup failure when we have an insanity. */ + if (sym->st_shndx == SHN_UNDEF || sym->st_value == 0) + return (0); + return ((Elf_Addr)ef->address + sym->st_value); + } + + /* + * XXX we can avoid doing a hash table based lookup for global + * symbols as well. This however is not always valid, so we'll + * just do it the hard way for now. Performance tweaks can + * always be added. + */ + + symbol = ef->strtab + sym->st_name; + + /* Force a lookup failure if the symbol name is bogus. */ + if (*symbol == 0) + return (0); + + return ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps)); +} diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c index 8eb7681f95ac..dd594051a998 100644 --- a/sys/kern/link_elf_obj.c +++ b/sys/kern/link_elf_obj.c @@ -904,8 +904,8 @@ relocate_file(elf_file_t ef) if (rel) { rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize); while (rel < rellim) { - symname = symbol_name(ef, rel->r_info); - if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, symname)) { + if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) { + symname = symbol_name(ef, rel->r_info); printf("link_elf: symbol %s undefined\n", symname); return ENOENT; } @@ -918,8 +918,8 @@ relocate_file(elf_file_t ef) if (rela) { relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize); while (rela < relalim) { - symname = symbol_name(ef, rela->r_info); - if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, symname)) { + if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) { + symname = symbol_name(ef, rela->r_info); printf("link_elf: symbol %s undefined\n", symname); return ENOENT; } @@ -932,8 +932,8 @@ relocate_file(elf_file_t ef) if (rel) { rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize); while (rel < rellim) { - symname = symbol_name(ef, rel->r_info); - if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, symname)) { + if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) { + symname = symbol_name(ef, rel->r_info); printf("link_elf: symbol %s undefined\n", symname); return ENOENT; } @@ -946,8 +946,8 @@ relocate_file(elf_file_t ef) if (rela) { relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize); while (rela < relalim) { - symname = symbol_name(ef, rela->r_info); - if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, symname)) { + if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) { + symname = symbol_name(ef, rela->r_info); printf("link_elf: symbol %s undefined\n", symname); return ENOENT; } @@ -1190,3 +1190,50 @@ link_elf_get_gp(linker_file_t lf) return (Elf_Addr)ef->got; } #endif + +/* + * Symbol lookup function that can be used when the symbol index is known (ie + * in relocations). It uses the symbol index instead of doing a fully fledged + * hash table based lookup when such is valid. For example for local symbols. + * This is not only more efficient, it's also more correct. It's not always + * the case that the symbol can be found through the hash table. + */ +Elf_Addr +elf_lookup(linker_file_t lf, Elf_Word symidx, int deps) +{ + elf_file_t ef = (elf_file_t)lf; + const Elf_Sym *sym; + const char *symbol; + + /* Don't even try to lookup the symbol if the index is bogus. */ + if (symidx >= ef->nchains) + return (0); + + sym = ef->symtab + symidx; + + /* + * Don't do a full lookup when the symbol is local. It may even + * fail because it may not be found through the hash table. + */ + if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) { + /* Force lookup failure when we have an insanity. */ + if (sym->st_shndx == SHN_UNDEF || sym->st_value == 0) + return (0); + return ((Elf_Addr)ef->address + sym->st_value); + } + + /* + * XXX we can avoid doing a hash table based lookup for global + * symbols as well. This however is not always valid, so we'll + * just do it the hard way for now. Performance tweaks can + * always be added. + */ + + symbol = ef->strtab + sym->st_name; + + /* Force a lookup failure if the symbol name is bogus. */ + if (*symbol == 0) + return (0); + + return ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps)); +} diff --git a/sys/powerpc/powerpc/elf_machdep.c b/sys/powerpc/powerpc/elf_machdep.c index 44ea9ef4c468..3a39ac6aa614 100644 --- a/sys/powerpc/powerpc/elf_machdep.c +++ b/sys/powerpc/powerpc/elf_machdep.c @@ -38,13 +38,13 @@ /* Process one elf relocation with addend. */ int -elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) +elf_reloc(linker_file_t lf, const void *data, int type) { Elf_Addr relocbase = (Elf_Addr) lf->address; Elf_Addr *where; Elf_Addr addr; Elf_Addr addend; - Elf_Word rtype; + Elf_Word rtype, symidx; const Elf_Rel *rel; const Elf_Rela *rela; @@ -54,12 +54,14 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) where = (Elf_Addr *) (relocbase + rel->r_offset); addend = *where; rtype = ELF_R_TYPE(rel->r_info); + symidx = ELF_R_SYM(rel->r_info); break; case ELF_RELOC_RELA: rela = (const Elf_Rela *)data; where = (Elf_Addr *) (relocbase + rela->r_offset); addend = rela->r_addend; rtype = ELF_R_TYPE(rela->r_info); + symidx = ELF_R_SYM(rela->r_info); break; default: panic("elf_reloc: unknown relocation mode %d\n", type); @@ -71,9 +73,8 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) break; case R_PPC_GLOB_DAT: - addr = (Elf_Addr) - linker_file_lookup_symbol(lf, sym, 1); - if (addr == NULL) + addr = elf_lookup(lf, symidx, 1); + if (addr == 0) return -1; addr += addend; if (*where != addr) @@ -82,9 +83,8 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) case R_PPC_JMP_SLOT: /* No point in lazy binding for kernel modules. */ - addr = (Elf_Addr) - linker_file_lookup_symbol(lf, sym, 1); - if (addr == NULL) + addr = elf_lookup(lf, symidx, 1); + if (addr == 0) return -1; if (*where != addr) *where = addr; diff --git a/sys/sparc64/sparc64/elf_machdep.c b/sys/sparc64/sparc64/elf_machdep.c index 3e6c79062d9f..592d9fb10155 100644 --- a/sys/sparc64/sparc64/elf_machdep.c +++ b/sys/sparc64/sparc64/elf_machdep.c @@ -168,13 +168,13 @@ static long reloc_target_bitmask[] = { /* Process one elf relocation with addend. */ int -elf_reloc(linker_file_t lf, const void *data, int type, const char *symname) +elf_reloc(linker_file_t lf, const void *data, int type) { const Elf_Rela *rela; Elf_Addr relocbase; Elf_Half *where32; Elf_Addr *where; - Elf_Word rtype; + Elf_Word rtype, symidx; Elf_Addr value; Elf_Addr mask; caddr_t addr; @@ -187,6 +187,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *symname) where = (Elf_Addr *)(relocbase + rela->r_offset); where32 = (Elf_Half *)where; rtype = ELF_R_TYPE(rela->r_info); + symidx = ELF_R_SYM(rela->r_info); if (rtype == R_SPARC_NONE) return (0); @@ -201,7 +202,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *symname) value = rela->r_addend; if (RELOC_RESOLVE_SYMBOL(rtype)) { - addr = linker_file_lookup_symbol(lf, symname, 1); + addr = elf_lookup(lf, symidx, 1); if (addr == 0) return (-1); value += (Elf_Addr)addr; diff --git a/sys/sys/linker.h b/sys/sys/linker.h index f138df7519a8..3b3edca33a0f 100644 --- a/sys/sys/linker.h +++ b/sys/sys/linker.h @@ -226,8 +226,9 @@ extern int kld_debug; #endif /* Support functions */ -int elf_reloc(linker_file_t _lf, const void *_rel, int _type, - const char *_sym); +int elf_reloc(linker_file_t _lf, const void *_rel, int _type); +Elf_Addr elf_lookup(linker_file_t, Elf_Word, int); + /* values for type */ #define ELF_RELOC_REL 1 #define ELF_RELOC_RELA 2 |
