Home | History | Annotate | Download | only in src
      1 /* Macros to enable writing native and generic ELF access code.
      2    Copyright (C) 2003 Red Hat, Inc.
      3    Written by Ulrich Drepper <drepper (at) redhat.com>, 2003.
      4 
      5    This program is Open Source software; you can redistribute it and/or
      6    modify it under the terms of the Open Software License version 1.0 as
      7    published by the Open Source Initiative.
      8 
      9    You should have received a copy of the Open Software License along
     10    with this program; if not, you may obtain a copy of the Open Software
     11    License version 1.0 from http://www.opensource.org/licenses/osl.php or
     12    by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
     13    3001 King Ranch Road, Ukiah, CA 95482.   */
     14 
     15 #ifdef HAVE_CONFIG_H
     16 # include <config.h>
     17 #endif
     18 
     19 #include <libebl.h>
     20 
     21 
     22 /* By default the linker is handling all architectures.  But it can
     23    be configured to be a native-only linker.  */
     24 #if NATIVE_ELF == 32
     25 /* 32-bit only.  */
     26 # define XElf_Ehdr Elf32_Ehdr
     27 # define XElf_Shdr Elf32_Shdr
     28 # define XElf_Off Elf32_Off
     29 # define XElf_Addr Elf32_Addr
     30 # define XElf_Half Elf32_Half
     31 # define XElf_Word Elf32_Word
     32 # define XElf_Xword Elf32_Word
     33 # define XElf_Sxword Elf32_Sword
     34 # define XElf_Versym Elf32_Versym
     35 # define XElf_Sym Elf32_Sym
     36 # define XElf_Rel Elf32_Rel
     37 # define XElf_Rela Elf32_Rela
     38 
     39 # define XElf_Ehdr_vardef(name) Elf32_Ehdr *name
     40 # define xelf_getehdr(elf, name) name = elf32_getehdr (elf)
     41 # define xelf_getehdr_copy(elf, name, copy) \
     42   (copy) = *(name = elf32_getehdr (elf))
     43 # define xelf_newehdr(elf, klass) elf32_newehdr (elf)
     44 # define xelf_update_ehdr(elf, ehdr) \
     45   /* nothing */ ((void) (elf), (void) (ehdr), 1)
     46 
     47 # define xelf_getclass(elf) ELFCLASS32
     48 
     49 # define XElf_Phdr_vardef(name) Elf32_Phdr *name
     50 # define xelf_newphdr(elf, n) elf32_newphdr (elf, n)
     51 # define xelf_getphdr(elf, idx, name) name = elf32_getphdr (elf) + idx
     52 # define xelf_getphdr_ptr(elf, idx, name) name = elf32_getphdr (elf) + idx
     53 # define xelf_update_phdr(elf, idx, phdr) \
     54   /* nothing */ ((void) (elf), (void) (idx), (void) (phdr), 1)
     55 
     56 # define XElf_Shdr_vardef(name) Elf32_Shdr *name
     57 # define xelf_getshdr(scn, name) name = elf32_getshdr (scn)
     58 # define xelf_getshdr_copy(scn, name, copy) \
     59   (copy) = *(name = elf32_getshdr (scn))
     60 # define xelf_update_shdr(scn, shdr) \
     61   /* nothing */ ((void) (scn), (void) (shdr), 1)
     62 
     63 # define XElf_Sym_vardef(name) Elf32_Sym *name
     64 # define xelf_getsym(data, idx, name) \
     65   name = &((Elf32_Sym *) (data)->d_buf)[idx]
     66 # define xelf_getsym_ptr(data, idx, name) \
     67   name = &((Elf32_Sym *) (data)->d_buf)[idx]
     68 # define xelf_getsymshndx(data, ndxdata, idx, name1, name2) \
     69   (name1 = &((Elf32_Sym *) ((data)->d_buf))[idx]);			      \
     70   name2 = (unlikely ((ndxdata) != NULL)					      \
     71 	   ? ((Elf32_Word *) ((ndxdata)->d_buf))[idx] : 0)
     72 # define xelf_update_sym(data, idx, sym) \
     73   /* nothing */ ((void) (data), (void) (idx), (void) (sym), 1)
     74 # define xelf_update_symshndx(data, ndxdata, idx, name1, name2, datachanged) \
     75   if (datachanged)							      \
     76     ((Elf32_Sym *) ((data)->d_buf))[idx] = *name1;			      \
     77   if (unlikely (ndxdata != NULL))					      \
     78     ((Elf32_Word *) ((ndxdata)->d_buf))[idx] = name2
     79 
     80 # define XElf_Versym_vardef(name) Elf32_Versym name
     81 # define xelf_getversym_copy(data, idx, name) \
     82   (name = ((Elf32_Versym *) ((data)->d_buf))[idx], &name)
     83 
     84 # define XElf_Dyn_vardef(name) Elf32_Dyn *name
     85 # define xelf_getdyn(data, idx, name) \
     86   name = &((Elf32_Dyn *) ((data)->d_buf))[idx]
     87 # define xelf_getdyn_ptr(data, idx, name) \
     88   name = &((Elf32_Dyn *) ((data)->d_buf))[idx]
     89 # define xelf_update_dyn(data, idx, name) \
     90   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
     91 
     92 # define XElf_Rel_vardef(name) Elf32_Rel *name
     93 # define xelf_getrel(data, idx, name) \
     94   name = &((Elf32_Rel *) ((data)->d_buf))[idx]
     95 # define xelf_getrel_ptr(data, idx, name) \
     96   name = &((Elf32_Rel *) ((data)->d_buf))[idx]
     97 # define xelf_update_rel(data, idx, name) \
     98   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
     99 
    100 # define XElf_Rela_vardef(name) Elf32_Rela *name
    101 # define xelf_getrela(data, idx, name) \
    102   name = &((Elf32_Rela *) ((data)->d_buf))[idx]
    103 # define xelf_getrela_ptr(data, idx, name) \
    104   name = &((Elf32_Rela *) ((data)->d_buf))[idx]
    105 # define xelf_update_rela(data, idx, name) \
    106   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
    107 
    108 # define XElf_Verdef_vardef(name) Elf32_Verdef *name
    109 # define xelf_getverdef(data, offset, name) \
    110   name = ((Elf32_Verdef *) ((char *) ((data)->d_buf) + (offset)))
    111 
    112 # define XElf_Verdaux_vardef(name) Elf32_Verdaux *name
    113 # define xelf_getverdaux(data, offset, name) \
    114   name = ((Elf32_Verdaux *) ((char *) ((data)->d_buf) + (offset)))
    115 
    116 # define XELF_ST_TYPE(info) ELF32_ST_TYPE (info)
    117 # define XELF_ST_BIND(info) ELF32_ST_BIND (info)
    118 # define XELF_ST_INFO(bind, type) ELF32_ST_INFO (bind, type)
    119 # define XELF_ST_VISIBILITY(info) ELF32_ST_VISIBILITY (info)
    120 
    121 # define XELF_R_SYM(info) ELF32_R_SYM (info)
    122 # define XELF_R_TYPE(info) ELF32_R_TYPE (info)
    123 # define XELF_R_INFO(sym, type) ELF32_R_INFO (sym, type)
    124 
    125 # define xelf_fsize(elf, type, cnt) \
    126   (__builtin_constant_p (type)						      \
    127    ? ({ size_t fsize;							      \
    128         switch (type)							      \
    129 	  {								      \
    130 	  case ELF_T_BYTE: fsize = 1; break;				      \
    131 	  case ELF_T_ADDR: fsize = sizeof (Elf32_Addr); break;		      \
    132 	  case ELF_T_DYN: fsize = sizeof (Elf32_Dyn); break;		      \
    133 	  case ELF_T_EHDR: fsize = sizeof (Elf32_Ehdr); break;		      \
    134 	  case ELF_T_HALF: fsize = sizeof (Elf32_Half); break;		      \
    135 	  case ELF_T_OFF: fsize = sizeof (Elf32_Off); break;		      \
    136 	  case ELF_T_PHDR: fsize = sizeof (Elf32_Phdr); break;		      \
    137 	  case ELF_T_RELA: fsize = sizeof (Elf32_Rela); break;		      \
    138 	  case ELF_T_REL: fsize = sizeof (Elf32_Rel); break;		      \
    139 	  case ELF_T_SHDR: fsize = sizeof (Elf32_Shdr); break;		      \
    140 	  case ELF_T_SWORD: fsize = sizeof (Elf32_Sword); break;	      \
    141 	  case ELF_T_SYM: fsize = sizeof (Elf32_Sym); break;		      \
    142 	  case ELF_T_WORD: fsize = sizeof (Elf32_Word); break;		      \
    143 	  case ELF_T_XWORD: fsize = sizeof (Elf32_Xword); break;	      \
    144 	  case ELF_T_SXWORD: fsize = sizeof (Elf32_Sxword); break;	      \
    145 	  case ELF_T_VDEF: fsize = sizeof (Elf32_Verdef); break;	      \
    146 	  case ELF_T_VDAUX: fsize = sizeof (Elf32_Verdaux); break;	      \
    147 	  case ELF_T_VNEED: fsize = sizeof (Elf32_Verneed); break;	      \
    148 	  case ELF_T_VNAUX: fsize = sizeof (Elf32_Vernaux); break;	      \
    149 	  case ELF_T_NHDR: fsize = sizeof (Elf32_Nhdr); break;		      \
    150 	  case ELF_T_SYMINFO: fsize = sizeof (Elf32_Syminfo); break;	      \
    151 	  case ELF_T_MOVE: fsize = sizeof (Elf32_Move); break;		      \
    152           default: fsize = 0; break;					      \
    153 	  }								      \
    154         fsize * (cnt); })						      \
    155    : gelf_fsize (elf, type, cnt, EV_CURRENT))
    156 #elif NATIVE_ELF == 64
    157 /* 64-bit only.  */
    158 # define XElf_Ehdr Elf64_Ehdr
    159 # define XElf_Shdr Elf64_Shdr
    160 # define XElf_Addr Elf64_Addr
    161 # define XElf_Half Elf64_Half
    162 # define XElf_Off Elf64_Off
    163 # define XElf_Word Elf64_Word
    164 # define XElf_Xword Elf64_Xword
    165 # define XElf_Sxword Elf64_Sxword
    166 # define XElf_Versym Elf64_Versym
    167 # define XElf_Sym Elf64_Sym
    168 # define XElf_Rel Elf64_Rel
    169 # define XElf_Rela Elf64_Rela
    170 
    171 # define XElf_Ehdr_vardef(name) Elf64_Ehdr *name
    172 # define xelf_getehdr(elf, name) name = elf64_getehdr (elf)
    173 # define xelf_getehdr_copy(elf, name, copy) \
    174   (copy) = *(name = elf64_getehdr (elf))
    175 # define xelf_newehdr(elf, klass) elf64_newehdr (elf)
    176 # define xelf_update_ehdr(elf, ehdr) \
    177   /* nothing */ ((void) (elf), (void) (ehdr), 1)
    178 
    179 # define xelf_getclass(elf) ELFCLASS32
    180 
    181 # define XElf_Phdr_vardef(name) Elf64_Phdr *name
    182 # define xelf_newphdr(elf, n) elf64_newphdr (elf, n)
    183 # define xelf_getphdr(elf, idx, name) name = elf64_getphdr (elf) + idx
    184 # define xelf_getphdr_ptr(elf, idx, name) name = elf64_getphdr (elf) + idx
    185 # define xelf_update_phdr(elf, idx, phdr) \
    186   /* nothing */ ((void) (elf), (void) (idx), (void) (phdr), 1)
    187 
    188 # define XElf_Shdr_vardef(name) Elf64_Shdr *name
    189 # define xelf_getshdr(scn, name) name = elf64_getshdr (scn)
    190 # define xelf_getshdr_copy(scn, name, copy) \
    191   (copy) = *(name = elf64_getshdr (scn))
    192 # define xelf_update_shdr(scn, shdr) \
    193   /* nothing */ ((void) (scn), (void) (shdr), 1)
    194 
    195 # define XElf_Sym_vardef(name) Elf64_Sym *name
    196 # define xelf_getsym(data, idx, name) \
    197   name = &((Elf64_Sym *) (data)->d_buf)[idx]
    198 # define xelf_getsym_ptr(data, idx, name) \
    199   name = &((Elf64_Sym *) (data)->d_buf)[idx]
    200 # define xelf_getsymshndx(data, ndxdata, idx, name1, name2) \
    201   (name1 = &((Elf64_Sym *) ((data)->d_buf))[idx]);			      \
    202   name2 = (unlikely ((ndxdata) != NULL)					      \
    203 	   ? ((Elf32_Word *) ((ndxdata)->d_buf))[idx] : 0)
    204 # define xelf_update_sym(data, idx, sym) \
    205   /* nothing */ ((void) (data), (void) (idx), (void) (sym), 1)
    206 # define xelf_update_symshndx(data, ndxdata, idx, name1, name2, datachanged) \
    207   if (datachanged)							      \
    208     ((Elf64_Sym *) ((data)->d_buf))[idx] = *name1;			      \
    209   if (ndxdata != NULL)							      \
    210     (((Elf32_Word *) ((ndxdata)->d_buf))[idx] = name2)
    211 
    212 # define XElf_Versym_vardef(name) Elf64_Versym name
    213 # define xelf_getversym_copy(data, idx, name) \
    214   (name = ((Elf64_Versym *) ((data)->d_buf))[idx], (&name))
    215 
    216 # define XElf_Dyn_vardef(name) Elf64_Dyn *name
    217 # define xelf_getdyn(data, idx, name) \
    218   name = &((Elf64_Dyn *) ((data)->d_buf))[idx]
    219 # define xelf_getdyn_ptr(data, idx, name) \
    220   name = &((Elf64_Dyn *) ((data)->d_buf))[idx]
    221 # define xelf_update_dyn(data, idx, name) \
    222   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
    223 
    224 # define XElf_Rel_vardef(name) Elf64_Rel *name
    225 # define xelf_getrel(data, idx, name) \
    226   name = &((Elf64_Rel *) ((data)->d_buf))[idx]
    227 # define xelf_getrel_ptr(data, idx, name) \
    228   name = &((Elf64_Rel *) ((data)->d_buf))[idx]
    229 # define xelf_update_rel(data, idx, name) \
    230   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
    231 
    232 # define XElf_Rela_vardef(name) Elf64_Rela *name
    233 # define xelf_getrela(data, idx, name) \
    234   name = &((Elf64_Rela *) ((data)->d_buf))[idx]
    235 # define xelf_getrela_ptr(data, idx, name) \
    236   name = &((Elf64_Rela *) ((data)->d_buf))[idx]
    237 # define xelf_update_rela(data, idx, name) \
    238   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
    239 
    240 # define XElf_Verdef_vardef(name) Elf64_Verdef *name
    241 # define xelf_getverdef(data, offset, name) \
    242   name = ((Elf64_Verdef *) ((char *) ((data)->d_buf) + (offset)))
    243 
    244 # define XElf_Verdaux_vardef(name) Elf64_Verdaux *name
    245 # define xelf_getverdaux(data, offset, name) \
    246   name = ((Elf64_Verdaux *) ((char *) ((data)->d_buf) + (offset)))
    247 
    248 # define XELF_ST_TYPE(info) ELF64_ST_TYPE (info)
    249 # define XELF_ST_BIND(info) ELF64_ST_BIND (info)
    250 # define XELF_ST_INFO(bind, type) ELF64_ST_INFO (bind, type)
    251 # define XELF_ST_VISIBILITY(info) ELF64_ST_VISIBILITY (info)
    252 
    253 # define XELF_R_SYM(info) ELF64_R_SYM (info)
    254 # define XELF_R_TYPE(info) ELF64_R_TYPE (info)
    255 # define XELF_R_INFO(sym, type) ELF64_R_INFO (sym, type)
    256 
    257 # define xelf_fsize(elf, type, cnt) \
    258   (__builtin_constant_p (type)						      \
    259    ? ({ size_t fsize;							      \
    260         switch (type)							      \
    261 	  {								      \
    262 	  case ELF_T_BYTE: fsize = 1; break;				      \
    263 	  case ELF_T_ADDR: fsize = sizeof (Elf64_Addr); break;		      \
    264 	  case ELF_T_DYN: fsize = sizeof (Elf64_Dyn); break;		      \
    265 	  case ELF_T_EHDR: fsize = sizeof (Elf64_Ehdr); break;		      \
    266 	  case ELF_T_HALF: fsize = sizeof (Elf64_Half); break;		      \
    267 	  case ELF_T_OFF: fsize = sizeof (Elf64_Off); break;		      \
    268 	  case ELF_T_PHDR: fsize = sizeof (Elf64_Phdr); break;		      \
    269 	  case ELF_T_RELA: fsize = sizeof (Elf64_Rela); break;		      \
    270 	  case ELF_T_REL: fsize = sizeof (Elf64_Rel); break;		      \
    271 	  case ELF_T_SHDR: fsize = sizeof (Elf64_Shdr); break;		      \
    272 	  case ELF_T_SWORD: fsize = sizeof (Elf64_Sword); break;	      \
    273 	  case ELF_T_SYM: fsize = sizeof (Elf64_Sym); break;		      \
    274 	  case ELF_T_WORD: fsize = sizeof (Elf64_Word); break;		      \
    275 	  case ELF_T_XWORD: fsize = sizeof (Elf64_Xword); break;	      \
    276 	  case ELF_T_SXWORD: fsize = sizeof (Elf64_Sxword); break;	      \
    277 	  case ELF_T_VDEF: fsize = sizeof (Elf64_Verdef); break;	      \
    278 	  case ELF_T_VDAUX: fsize = sizeof (Elf64_Verdaux); break;	      \
    279 	  case ELF_T_VNEED: fsize = sizeof (Elf64_Verneed); break;	      \
    280 	  case ELF_T_VNAUX: fsize = sizeof (Elf64_Vernaux); break;	      \
    281 	  case ELF_T_NHDR: fsize = sizeof (Elf64_Nhdr); break;		      \
    282 	  case ELF_T_SYMINFO: fsize = sizeof (Elf64_Syminfo); break;	      \
    283 	  case ELF_T_MOVE: fsize = sizeof (Elf64_Move); break;		      \
    284           default: fsize = 0; break;					      \
    285 	  }								      \
    286         fsize * (cnt); })						      \
    287    : gelf_fsize (elf, type, cnt, EV_CURRENT))
    288 #else
    289 # include <gelf.h>
    290 
    291 /* Generic linker.  */
    292 # define XElf_Ehdr GElf_Ehdr
    293 # define XElf_Shdr GElf_Shdr
    294 # define XElf_Addr GElf_Addr
    295 # define XElf_Half GElf_Half
    296 # define XElf_Off GElf_Off
    297 # define XElf_Word GElf_Word
    298 # define XElf_Xword GElf_Xword
    299 # define XElf_Sxword GElf_Sxword
    300 # define XElf_Versym GElf_Versym
    301 # define XElf_Sym GElf_Sym
    302 # define XElf_Rel GElf_Rel
    303 # define XElf_Rela GElf_Rela
    304 
    305 # define XElf_Ehdr_vardef(name) GElf_Ehdr name##_mem; GElf_Ehdr *name
    306 # define xelf_getehdr(elf, name) name = gelf_getehdr (elf, &name##_mem)
    307 # define xelf_getehdr_copy(elf, name, copy) \
    308   name = gelf_getehdr (elf, &(copy))
    309 # define xelf_newehdr(elf, klass) gelf_newehdr (elf, klass)
    310 # define xelf_update_ehdr(elf, ehdr) gelf_update_ehdr (elf, ehdr)
    311 
    312 # define xelf_getclass(elf) gelf_getclass (elf)
    313 
    314 # define XElf_Phdr_vardef(name) GElf_Phdr name##_mem; GElf_Phdr *name
    315 # define xelf_newphdr(elf, n) gelf_newphdr (elf, n)
    316 # define xelf_getphdr(elf, idx, name) \
    317   name = gelf_getphdr (elf, idx, &name##_mem)
    318 # define xelf_getphdr_ptr(elf, idx, name) \
    319   name = &name##_mem
    320 # define xelf_update_phdr(elf, idx, phdr) \
    321   gelf_update_phdr (elf, idx, phdr)
    322 
    323 # define XElf_Shdr_vardef(name) GElf_Shdr name##_mem; GElf_Shdr *name
    324 # define xelf_getshdr(scn, name) name = gelf_getshdr (scn, &name##_mem)
    325 # define xelf_getshdr_copy(scn, name, copy) \
    326   name = gelf_getshdr (scn, &(copy))
    327 # define xelf_update_shdr(scn, shdr) gelf_update_shdr (scn, shdr)
    328 
    329 # define XElf_Sym_vardef(name) GElf_Sym name##_mem; GElf_Sym *name
    330 # define xelf_getsym(data, idx, name) \
    331   name = gelf_getsym (data, idx, &name##_mem)
    332 # define xelf_getsym_ptr(data, idx, name) \
    333   name = &name##_mem
    334 # define xelf_getsymshndx(data, ndxdata, idx, name1, name2) \
    335   name1 = gelf_getsymshndx (data, ndxdata, idx, &name1##_mem, &(name2))
    336 # define xelf_update_sym(data, idx, sym) gelf_update_sym (data, idx, sym)
    337 # define xelf_update_symshndx(data, ndxdata, idx, name1, name2, datachanged) \
    338   gelf_update_symshndx (data, ndxdata, idx, name1, name2)
    339 
    340 # define XElf_Versym_vardef(name) GElf_Versym name
    341 # define xelf_getversym_copy(data, idx, name) \
    342   gelf_getversym (data, idx, &name)
    343 
    344 # define XElf_Dyn_vardef(name) GElf_Dyn name##_mem; GElf_Dyn *name
    345 # define xelf_getdyn(data, idx, name) \
    346   name = gelf_getdyn (data, idx, &name##_mem)
    347 # define xelf_getdyn_ptr(data, idx, name) \
    348   name = &name##_mem
    349 # define xelf_update_dyn(data, idx, name) \
    350   gelf_update_dyn (data, idx, name)
    351 
    352 # define XElf_Rel_vardef(name) GElf_Rel name##_mem; GElf_Rel *name
    353 # define xelf_getrel(data, idx, name) \
    354   name = gelf_getrel (data, idx, &name##_mem)
    355 # define xelf_getrel_ptr(data, idx, name) \
    356   name = &name##_mem
    357 # define xelf_update_rel(data, idx, name) \
    358   gelf_update_rel (data, idx, name)
    359 
    360 # define XElf_Rela_vardef(name) GElf_Rela name##_mem; GElf_Rela *name
    361 # define xelf_getrela(data, idx, name) \
    362   name = gelf_getrela (data, idx, &name##_mem)
    363 # define xelf_getrela_ptr(data, idx, name) \
    364   name = &name##_mem
    365 # define xelf_update_rela(data, idx, name) \
    366   gelf_update_rela (data, idx, name)
    367 
    368 # define XElf_Verdef_vardef(name) GElf_Verdef name##_mem; GElf_Verdef *name
    369 # define xelf_getverdef(data, offset, name) \
    370   name = gelf_getverdef (data, offset, &name##_mem)
    371 
    372 # define XElf_Verdaux_vardef(name) GElf_Verdaux name##_mem; GElf_Verdaux *name
    373 # define xelf_getverdaux(data, offset, name) \
    374   name = gelf_getverdaux (data, offset, &name##_mem)
    375 
    376 # define XELF_ST_TYPE(info) GELF_ST_TYPE (info)
    377 # define XELF_ST_BIND(info) GELF_ST_BIND (info)
    378 # define XELF_ST_INFO(bind, type) GELF_ST_INFO (bind, type)
    379 # define XELF_ST_VISIBILITY(info) GELF_ST_VISIBILITY (info)
    380 
    381 # define XELF_R_SYM(info) GELF_R_SYM (info)
    382 # define XELF_R_TYPE(info) GELF_R_TYPE (info)
    383 # define XELF_R_INFO(sym, type) GELF_R_INFO (sym, type)
    384 
    385 # define xelf_fsize(elf, type, cnt) \
    386   gelf_fsize (elf, type, cnt, EV_CURRENT)
    387 #endif
    388